集合
.NET 執行時間提供許多集合類型,可儲存和管理相關物件的群組。 C# 語言可辨識某些集合類型,例如 System.Array 、 System.Span<T> 和 System.Memory<T> 。 此外,類似 的 System.Collections.Generic.IEnumerable<T> 介面會以語言辨識,以列舉集合的專案。
集合提供彈性的方式來處理物件群組。 您可以依照下列特性來分類不同的集合:
- 元素存取 :可以列舉每個集合來依序存取每個元素。 某些集合會依 索引 存取元素,該元素在已排序的集合中的位置。 最常見的範例是 System.Collections.Generic.List<T> 。 其他集合會依 索引鍵 存取元素,其中值 與單 一 索引鍵 相關聯。 最常見的範例是 System.Collections.Generic.Dictionary<TKey,TValue> 。 您可以根據應用程式存取元素的方式,選擇這些集合類型。
- 效能設定檔:每個集合都有不同的效能設定檔 ,可用於新增專案、尋找專案或移除專案等動作。 您可以根據應用程式中最常使用的作業來挑選集合類型。
- 動態 成長和縮小:支援動態新增或移除元素的大部分集合。 值得注意的是, Array 、 System.Span<T> 和 System.Memory<T> 不。
除了這些特性之外,執行時間還提供特製化集合,以防止新增或移除專案或修改集合的元素。 其他特製化集合為多執行緒應用程式中的平行存取提供安全性。
您可以在 .NET API 參考 中找到 所有集合類型。 如需詳細資訊,請參閱 常用集合類型和 選取集合類別 。
注意
針對本文中的範例,您可能需要新增 和 命名空間的 using 指示詞 System.Collections.Generic
。 System.Linq
陣列是以 來表示 System.Array ,並且具有 C# 語言的語法支援。 此語法提供陣列變數更簡潔的宣告。
System.Span<T> 是一種 ref struct
類型,可在一連串元素上提供快照集,而不復制這些專案。 編譯器會強制執行安全規則,以確保 Span
在它所參考的序列不再位於範圍內之後,無法存取 。 它用於許多 .NET API 來改善效能。 Memory<T> 當您無法使用 ref struct
類型時,會提供類似的行為。
從 C# 12 開始,所有集合類型都可以使用 Collection 運算式 初始化。
可編制索引的集合
可編制索引的集合是您可以使用其索引來存取每個元素的集合 。 其 索引 是序列中元素之前的元素數目。 因此,依索引 0
的元素參考是第一個專案、index 1
是第二個專案等等。 這些範例會使用 類別 List<T> 。 這是最常見的可索引集合。
下列範例會建立並初始化字串清單、移除專案,並將專案加入清單結尾。 每次修改之後,它會使用 foreach 語句或迴圈逐一 for
查看字串:
// Create a list of strings by using a
// collection initializer.
List<string> salmons = ["chinook", "coho", "pink", "sockeye"];
// Iterate through the list.
foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook coho pink sockeye
// Remove an element from the list by specifying
// the object.
salmons.Remove("coho");
// Iterate using the index:
for (var index = 0; index < salmons.Count; index++)
{
Console.Write(salmons[index] + " ");
}
// Output: chinook pink sockeye
// Add the removed element
salmons.Add("coho");
// Iterate through the list.
foreach (var salmon in salmons)
{
Console.Write(salmon + " ");
}
// Output: chinook pink sockeye coho
下列範例會依索引從清單中移除元素。 foreach
它不是 語句,而是使用 for
以遞減順序反覆運算的 語句。 方法 RemoveAt 會在移除的專案之後,讓元素具有較低的索引值。
List<int> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// Remove odd numbers.
for (var index = numbers.Count - 1; index >= 0; index--)
{
if (numbers[index] % 2 == 1)
{
// Remove the element by specifying
// the zero-based index in the list.
numbers.RemoveAt(index);
}
}
// Iterate through the list.
// A lambda expression is placed in the ForEach method
// of the List(T) object.
numbers.ForEach(
number => Console.Write(number + " "));
// Output: 0 2 4 6 8
如需 List<T> 中的項目類型,您也可以定義自己的類別。 在下列範例中,List<T> 使用的 Galaxy
類別是在程式碼中定義的。
private static void IterateThroughList()
{
var theGalaxies = new List<Galaxy>
{
new (){ Name="Tadpole", MegaLightYears=400},
new (){ Name="Pinwheel", MegaLightYears=25},
new (){ Name="Milky Way", MegaLightYears=0},
new (){ Name="Andromeda", MegaLightYears=3}
};
foreach (Galaxy theGalaxy in theGalaxies)
{
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
}
// Output:
// Tadpole 400
// Pinwheel 25
// Milky Way 0
// Andromeda 3
}
public class Galaxy
{
public string Name { get; set; }
public int MegaLightYears { get; set; }
}
索引鍵/值組集合
這些範例會使用 類別 Dictionary<TKey,TValue> 。 這是最常見的字典集合。 字典集合可讓您使用每個專案的索引鍵來存取集合中的元素。 加入字典中的每一個項目都是由值及其關聯索引鍵所組成。
下列範例會使用 foreach
陳述式建立 Dictionary
集合並逐一查看字典。
private static void IterateThruDictionary()
{
Dictionary<string, Element> elements = BuildDictionary();
foreach (KeyValuePair<string, Element> kvp in elements)
{
Element theElement = kvp.Value;
Console.WriteLine("key: " + kvp.Key);
Console.WriteLine("values: " + theElement.Symbol + " " +
theElement.Name + " " + theElement.AtomicNumber);
}
}
public class Element
{
public required string Symbol { get; init; }
public required string Name { get; init; }
public required int AtomicNumber { get; init; }
}
private static Dictionary<string, Element> BuildDictionary() =>
new ()
{
{"K",
new (){ Symbol="K", Name="Potassium", AtomicNumber=19}},
{"Ca",
new (){ Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{"Sc",
new (){ Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{"Ti",
new (){ Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};
下列範例會使用 ContainsKey 方法和 Dictionary
的 Item[] 屬性來依索引鍵快速尋找項目。 藉由使用 C# 中的 elements[symbol]
,Item
屬性可讓您存取 elements
集合中的項目。
if (elements.ContainsKey(symbol) == false)
{
Console.WriteLine(symbol + " not found");
}
else
{
Element theElement = elements[symbol];
Console.WriteLine("found: " + theElement.Name);
}
下列範例會改用 TryGetValue 方法來依索引鍵快速尋找專案。
if (elements.TryGetValue(symbol, out Element? theElement) == false)
Console.WriteLine(symbol + " not found");
else
Console.WriteLine("found: " + theElement.Name);
迭代器
「迭代器」是用來在集合上執行自訂反覆項目。 迭代器可以是方法或 get
存取子。 迭代器會使用 yield return 陳述式,一次一個地傳回集合中的每個項目。
您會使用 foreach 陳述式來呼叫迭代器。 foreach
迴圈的每個反覆項目都會呼叫迭代器。 在迭代器中到達 yield return
陳述式時,會傳回運算式,並保留程式碼中的目前位置。 下一次呼叫迭代器時,便會從這個位置重新開始執行。
如需詳細資訊,請參閱迭代器 (C#)。
下列範例使用了 iterator 方法。 反覆運算器方法具有 yield return
迴圈內的 for
語句。 在 ListEvenNumbers
方法中,foreach
陳述式主體的每個反覆項目都會建立對 Iterator 方法的呼叫,這個方法將繼續執行下一個 yield return
陳述式。
private static void ListEvenNumbers()
{
foreach (int number in EvenSequence(5, 18))
{
Console.Write(number.ToString() + " ");
}
Console.WriteLine();
// Output: 6 8 10 12 14 16 18
}
private static IEnumerable<int> EvenSequence(
int firstNumber, int lastNumber)
{
// Yield even numbers in the range.
for (var number = firstNumber; number <= lastNumber; number++)
{
if (number % 2 == 0)
{
yield return number;
}
}
}
LINQ 和集合
語言整合式查詢 (LINQ) 可用來存取集合。 LINQ 查詢提供篩選、排序和分組功能。 如需詳細資訊,請參閱開始使用 C# 中的 LINQ。
下列範例會對泛型 List
執行 LINQ 查詢。 LINQ 查詢會傳回包含結果的不同集合。
private static void ShowLINQ()
{
List<Element> elements = BuildList();
// LINQ Query.
var subset = from theElement in elements
where theElement.AtomicNumber < 22
orderby theElement.Name
select theElement;
foreach (Element theElement in subset)
{
Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber);
}
// Output:
// Calcium 20
// Potassium 19
// Scandium 21
}
private static List<Element> BuildList() => new()
{
{ new(){ Symbol="K", Name="Potassium", AtomicNumber=19}},
{ new(){ Symbol="Ca", Name="Calcium", AtomicNumber=20}},
{ new(){ Symbol="Sc", Name="Scandium", AtomicNumber=21}},
{ new(){ Symbol="Ti", Name="Titanium", AtomicNumber=22}}
};
意見反應
提交並檢視相關的意見反應