[.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 开发中处理数据集合的首选方式。理解这些核心接口和常用的集合类的特性和适用场景,能够帮助你编写更高效、更安全、更易于维护的代码。在选择集合类型时,请根据你的具体需求(例如,是否需要索引访问、是否需要唯一元素、是否需要排序、频繁的插入/删除操作等)进行选择。

相关推荐
kingwebo'sZone6 小时前
一次找不到“无法加载dll 对应的”,多媒体没有启用(需要安装mediaplayer)
c#
zxbmmmmmmmmm6 小时前
Avalonia源码解读:Grid(网格控件)
c#·xaml·avalonia
꧁执笔小白꧂7 小时前
.Net-Avalonia学习笔记(目录)
c#·avalonia
军训猫猫头7 小时前
3.NModbus4 长距离多设备超时 C# + WPF 完整示例
c#·.net·wpf·modbus
CPU不够了7 小时前
winsw实现windows服务
windows
TheNextByte17 小时前
适用于Windows和Mac电脑的Android文件传输工具
windows·macos·电脑
石像鬼₧魂石7 小时前
Fail2Ban 一键部署 + 管理脚本(可直接执行)
linux·windows·学习·ubuntu
石像鬼₧魂石8 小时前
Fail2Ban 实战终极速查表
linux·windows·学习·ubuntu
缺点内向8 小时前
C# 中如何从 URL 下载 Word 文档:基于 Spire.Doc 的高效解决方案
开发语言·c#·word