Skip to content

C# - 集合

集合是用于存储、管理和操作对象组的类。C# 在 System.Collections.Generic 命名空间中提供了一套丰富的集合类,这对于现代应用程序开发至关重要。

现代 C# 开发专门使用泛型集合(例如,List<T>、Dictionary<TKey, TValue>)。 <T> 表示一个类型参数,它允许你创建针对特定数据类型(如用于整数的 List<int> 或用于字符串的 List<string>)强类型化的集合。

泛型集合的优势:

  • 类型安全:编译器强制只允许添加正确类型的项,从而防止运行时错误。
  • 性能:它们避免了非泛型集合在处理值类型(如 int 或 struct)时发生的“装箱”(boxing)和“拆箱”(unboxing)的性能开销。
  • IntelliSense 支持:因为类型已知,你的代码编辑器能提供更好的自动补全和错误检查。

关于遗留集合的说明: 较旧的 C# 代码可能会使用 System.Collections 命名空间中的非泛型集合,例如 ArrayList 和 Hashtable。由于它们缺乏类型安全且性能较低,这些集合被认为是遗留的,不应在新代码中使用。

以下是最常用的泛型集合:

List<T> 是 ArrayList 的现代、类型安全等价物。它表示一个强类型的对象列表,可以通过索引访问。它的尺寸会随着你添加元素而动态增长。

using System;
using System.Collections.Generic;
// 创建一个字符串列表
var fruits = new List<string> { "Apple", "Banana", "Cherry" };
// 添加一个元素
fruits.Add("Date");
// 通过索引访问
Console.WriteLine($"The first fruit is: {fruits[0]}"); // Output: The first fruit is: Apple
// 遍历列表
foreach (var fruit in fruits)
{
Console.WriteLine(fruit);
}

2. Dictionary<TKey, TValue> - 键值存储

Section titled “2. Dictionary<TKey, TValue> - 键值存储”

Dictionary<TKey, TValue> 存储键值对,提供基于键的极快查找。它是 Hashtable 的现代替代品。

using System;
using System.Collections.Generic;
var userAges = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 }
};
// 添加一个新条目
userAges["Charlie"] = 35;
// 通过键检索值
if (userAges.TryGetValue("Alice", out int age))
{
Console.WriteLine($"Alice's age is: {age}"); // Output: Alice's age is: 30
}
// 检查是否存在
if (userAges.ContainsKey("David"))
{
Console.WriteLine("David exists.");
} else {
Console.WriteLine("David does not exist.");
}

HashSet<T> 包含一组唯一的元素。它对检查集合中是否存在某项进行了高度优化。

using System;
using System.Collections.Generic;
var uniqueTags = new HashSet<string> { "csharp", "dotnet", "programming" };
// 添加重复项会返回 false 且不会改变集合
bool added = uniqueTags.Add("csharp"); // returns false
Console.WriteLine($"Added duplicate 'csharp': {added}");
// 快速包含性检查
if (uniqueTags.Contains("dotnet"))
{
Console.WriteLine("The set contains 'dotnet'.");
}
// 输出:
// Added duplicate 'csharp': False
// The set contains 'dotnet'.

4. Queue<T>(先进先出 FIFO)与 Stack<T>(后进先出 LIFO)

Section titled “4. Queue<T>(先进先出 FIFO)与 Stack<T>(后进先出 LIFO)”

Queue<T> 是一种“先进先出”(First-In, First-Out, FIFO)的集合,就像商店里的队伍。Stack<T> 是一种“后进先出”(Last-In, First-Out, LIFO)的集合,就像一叠盘子。

// 队列示例 (FIFO)
var taskQueue = new Queue<string>();
taskQueue.Enqueue("Task 1");
taskQueue.Enqueue("Task 2");
Console.WriteLine(taskQueue.Dequeue()); // Output: Task 1
// 堆栈示例 (LIFO)
var browserHistory = new Stack<string>();
browserHistory.Push("Page 1");
browserHistory.Push("Page 2");
Console.WriteLine(browserHistory.Pop()); // Output: Page 2

语言集成查询(Language-Integrated Query, LINQ)为实现 IEnumerable<T> 的任何集合提供了强大且可读的语法,用于筛选、排序和转换数据。

using System.Collections.Generic;
using System.Linq;
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 使用 LINQ 查找所有大于 5 的偶数
var results = numbers
.Where(n => n % 2 == 0) // 筛选
.Where(n => n > 5); // 链接另一个筛选条件
Console.WriteLine("Even numbers greater than 5:");
foreach (var number in results)
{
Console.WriteLine(number);
}
// 输出:
// Even numbers greater than 5:
// 6
// 8
// 10