[.NET] 中 System.Collections.Generic命名空间详解

文章目录

System.Collections.Generic 命名空间是 .NET Framework 和 .NET (Core) 中非常重要的一个命名空间。它引入了泛型集合的概念,

与非泛型集合相比

与 System.Collections 中的非泛型集合相比,泛型集合具有以下关键优势

  • 类型安全 (Type Safety):

在编译时就能检查集合中元素的类型,避免了运行时的类型转换异常 (InvalidCastException)。

  • 性能提升 (Performance Improvement)

由于避免了值类型和引用类型之间的装箱(boxing)和拆箱(unboxing)操作,性能通常更高。

  • 代码可读性和可维护性增强 (Improved Code Readability and Maintainability)

通过指定集合中元素的类型,代码意图更加清晰。

下面将介绍 System.Collections.Generic 命名空间中一些最常用和重要的接口和类,并给出相应的 C# 示例。

核心接口

IEnumerable

定义了用于遍历泛型集合的迭代器。它是所有泛型集合的基础接口,支持 foreach 循环。

csharp 复制代码
public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

示例:

csharp 复制代码
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
foreach (string name in names)
{
    Console.WriteLine(name);
}

IEnumerator

支持在泛型集合上进行简单迭代,并提供对当前类型化元素的访问。

csharp 复制代码
public interface IEnumerator<out T> : IEnumerator, IDisposable
{
    new T Current { get; }
}

示例 (通常不直接使用,而是通过 IEnumerable.GetEnumerator() 获取):

csharp 复制代码
List<int> numbers = new List<int> { 10, 20, 30 };
IEnumerator<int> enumerator = numbers.GetEnumerator();
while (enumerator.MoveNext())
{
    Console.WriteLine(enumerator.Current);
}

ICollection

继承自 IEnumerable,定义了泛型集合的大小、枚举器和同步的基本操作。

csharp 复制代码
public interface ICollection<T> : IEnumerable<T>, IEnumerable
{
    int Count { get; }
    bool IsReadOnly { get; }
    void Add(T item);
    void Clear();
    bool Contains(T item);
    void CopyTo(T[] array, int arrayIndex);
    bool Remove(T item);
}

示例 (以 List 为例):

csharp 复制代码
List<double> prices = new List<double>();
prices.Add(9.99);
prices.Add(19.99);
Console.WriteLine($"价格数量: {prices.Count}");
Console.WriteLine($"是否只读: {prices.IsReadOnly}");
bool containsTen = prices.Contains(10.00);
Console.WriteLine($"是否包含 10.00: {containsTen}");
double[] priceArray = new double[prices.Count];
prices.CopyTo(priceArray, 0);
prices.Remove(9.99);
prices.Clear();

IList

继承自 ICollection,表示可通过索引单独访问的对象的泛型集合。

csharp 复制代码
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
    T this[int index] { get; set; }
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);
}

示例 (List 实现了 IList):

csharp 复制代码
List<string> colors = new List<string> { "Red", "Green", "Blue" };
Console.WriteLine($"第二个颜色: {colors[1]}");
colors[1] = "Yellow";
colors.Insert(0, "Purple");
int blueIndex = colors.IndexOf("Blue");
Console.WriteLine($"蓝色索引: {blueIndex}");
colors.RemoveAt(3);

IDictionary<TKey, TValue>

继承自 ICollection<KeyValuePair<TKey, TValue>>,表示键/值对的泛型集合。

csharp 复制代码
public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
{
    ICollection<TKey> Keys { get; }
    ICollection<TValue> Values { get; }
    TValue this[TKey key] { get; set; }
    void Add(TKey key, TValue value);
    bool ContainsKey(TKey key);
    bool Remove(TKey key);
    bool TryGetValue(TKey key, out TValue value);
}

示例 (Dictionary<TKey, TValue> 实现了 IDictionary<TKey, TValue>):

csharp 复制代码
Dictionary<string, int> ages = new Dictionary<string, int>();
ages.Add("Alice", 30);
ages["Bob"] = 25;
Console.WriteLine($"Alice 的年龄: {ages["Alice"]}");
bool hasCharlie = ages.ContainsKey("Charlie");
Console.WriteLine($"是否包含 Charlie: {hasCharlie}");
int bobAge;
if (ages.TryGetValue("Bob", out bobAge))
{
    Console.WriteLine($"Bob 的年龄 (TryGetValue): {bobAge}");
}
ages.Remove("Alice");

常用泛型集合类

List

表示一个可使用索引访问的对象的强类型化列表。它提供了动态数组的功能,可以根据需要自动调整大小。

csharp 复制代码
List<int> scores = new List<int>();
scores.Add(85);
scores.Add(92);
scores.Sort();
foreach (int score in scores)
{
    Console.WriteLine(score);
}

Dictionary<TKey, TValue>

表示一个键/值对的集合,这些键是唯一的。它提供了快速的基于键的查找。

csharp 复制代码
Dictionary<string, string> countryCodes = new Dictionary<string, string>();
countryCodes.Add("China", "CN");
countryCodes["United States"] = "US";
Console.WriteLine($"中国的代码: {countryCodes["China"]}");

HashSet

表示一组唯一的元素。它提供了高效的集合运算,如并集、交集、差集等。

csharp 复制代码
HashSet<string> uniqueNames = new HashSet<string>();
uniqueNames.Add("Alice");
uniqueNames.Add("Bob");
uniqueNames.Add("Alice"); // 不会重复添加
Console.WriteLine($"唯一名字数量: {uniqueNames.Count}");
bool containsBob = uniqueNames.Contains("Bob");
Console.WriteLine($"是否包含 Bob: {containsBob}");

Queue

表示对象的先进先出 (FIFO) 集合。

csharp 复制代码
Queue<string> messageQueue = new Queue<string>();
messageQueue.Enqueue("Message 1");
messageQueue.Enqueue("Message 2");
string firstMessage = messageQueue.Dequeue();
Console.WriteLine($"出队: {firstMessage}");
Console.WriteLine($"队列中剩余数量: {messageQueue.Count}");
string peekMessage = messageQueue.Peek();
Console.WriteLine($"队首元素 (不移除): {peekMessage}");

Stack

表示对象的后进先出 (LIFO) 集合。

csharp 复制代码
Stack<int> callStack = new Stack<int>();
callStack.Push(10);
callStack.Push(20);
int topElement = callStack.Pop();
Console.WriteLine($"出栈: {topElement}");
Console.WriteLine($"栈中剩余数量: {callStack.Count}");
int peekElement = callStack.Peek();
Console.WriteLine($"栈顶元素 (不移除): {peekElement}");

SortedList<TKey, TValue>

表示根据键进行排序的键/值对集合。

csharp 复制代码
SortedList<string, int> studentGrades = new SortedList<string, int>();
studentGrades.Add("Charlie", 95);
studentGrades.Add("Alice", 88);
studentGrades.Add("Bob", 92);
foreach (KeyValuePair<string, int> entry in studentGrades)
{
    Console.WriteLine($"{entry.Key}: {entry.Value}"); // 输出会按字母顺序排序
}

LinkedList

表示一个双向链表。它允许在列表中任何位置进行高效的插入和删除操作。

csharp 复制代码
LinkedList<string> linkedList = new LinkedList<string>();
linkedList.AddLast("Node 1");
LinkedListNode<string> node2 = linkedList.AddLast("Node 2");
linkedList.AddBefore(node2, "New Node");
foreach (string node in linkedList)
{
    Console.WriteLine(node);
}

其他重要的泛型接口

IComparer

定义了比较同一类型的两个对象的方法,用于自定义排序逻辑。

csharp 复制代码
public class PersonComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Name.CompareTo(y.Name);
    }
}

class Person
{
    public string Name { get; set; }
}

List<Person> people = new List<Person> { new Person { Name = "Bob" }, new Person { Name = "Alice" } };
people.Sort(new PersonComparer());
foreach (Person person in people)
{
    Console.WriteLine(person.Name); // 输出: Alice, Bob
}

IEqualityComparer

定义了确定两个对象是否相等以及为对象生成哈希代码的方法,用于自定义集合中的相等性比较(例如在 Dictionary<TKey, TValue> 和 HashSet 中)。

csharp 复制代码
public class CaseInsensitiveStringEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
    }

    public int GetHashCode(string obj)
    {
        return obj?.ToLowerInvariant().GetHashCode() ?? 0;
    }
}

HashSet<string> uniqueNamesIgnoreCase = new HashSet<string>(new CaseInsensitiveStringEqualityComparer());
uniqueNamesIgnoreCase.Add("Alice");
uniqueNamesIgnoreCase.Add("alice"); // 不会重复添加
Console.WriteLine($"不区分大小写的唯一名字数量: {uniqueNamesIgnoreCase.Count}"); // 输出: 1

总结

System.Collections.Generic 命名空间提供了强大且类型安全的集合类和接口,是 .NET 开发中处理数据集合的首选方式。理解这些核心接口和常用的集合类的特性和适用场景,能够帮助你编写更高效、更安全、更易于维护的代码。在选择集合类型时,请根据你的具体需求(例如,是否需要索引访问、是否需要唯一元素、是否需要排序、频繁的插入/删除操作等)进行选择。

相关推荐
YCOSA20253 小时前
雨晨 Windows 10 企业版 LTSC x64 中度精简 1809 迎双节 17763.9257 特别版
windows
sukalot4 小时前
windows 驱动实例分析系列: HidHide 驱动分析 - drivers 篇(四)
windows·驱动开发
Neil20135 小时前
ajax跨域请求
c#
唐青枫6 小时前
别把 Razor 当成几段 HTML:C#.NET Razor Pages、MVC 视图与实战详解
c#·.net
ι:9 小时前
NUC12 Pro 安装 Ubuntu 24.04 LTS 详细教程
linux·windows·ubuntu·nuc
YCOSA20259 小时前
微软宣布将于10月7日举行Windows与Surface发布会,聚焦“Windows、NVIDIA RTX Spark、Surface,以及更广泛PC生态”
windows
Source.Liu10 小时前
【A11】 labelprinter(Tauri 版)新建步骤
windows·rust
Punchline27811 小时前
解决 Windows 环境变量 Path 设置时提示“字符太长”的完整指南
windows·环境变量·path
chushiyunen12 小时前
claude code笔记(二)、claude桌面端(内网不好用)
windows
d_benhua12 小时前
以太网测试步骤
windows