C# IEnumerable<T>、IEnumerator<T>、List<T>、ArrayList、[]数组各各的区别

本文详细比较了.NET Framework中的各种集合类,如ArrayList、List&lt;T&gt;、ICollection&lt;T&gt;、IList&lt;T&gt;等,并阐述了它们之间的继承关系及使用场景。
List <T>是ArrayList的泛型,ArrayList里边的数据类型是object,List <T>里边的是具体的某种类型,ArrayList类似于向量,可以存储不同的数据类型在一个数组里边(转换为了object)。

一般使用的时候尽量使用List <T>,因为ArrayList存取都要进行一次转换。

[]类型的数组类似于List <T>,不同的是[]是定长的,而List <T>是长度可变的数组
ICollection主要针对静态集合;IList主要针对动态集合
IEnumerable <T>继承自IEnumerable
ICollection <T>继承自IEnumerable <T>
IList <T>继承自ICollection <T>
IEnumerable接口
实现了IEnumerable接口的集合表明该集合能够提供一个enumerator(枚举器)对象,支持当前的遍历集合。IEnumerable接口只有一个成员GetEnumerator()方法。
IList接口和ArrayList类的目的是实现动态数组,ArrayList是IList的一个实现。

IEnumerable表明对象是不确定类型的集合并支持简单迭代,是不是定长根本不关心...

IEnumerable <T>表明对象是指定类型的集合并支持简单迭代,是不是定长根本不关心...

ICollection是IEnumerable接口的派生接口,表明对象是不确定类型的集合并支持简单迭代,而且定义了集合的大小、枚举数和同步方法,这里的大小是指可以是定长的也可以是不定长的...

IList是ICollection和IEnumerable的派生接口,表明对象是不确定类型的集合并支持简单迭代,而且定义了集合的大小、枚举数和同步方法,还可以按照索引单独访问,这里的大小是指可以是定长的也可以是不定长的...

ArrayList类是IList接口的实现,表明对象是不确定类型的大小可按需动态增加的数组...

List <T>类是IList <T>接口的实现,是ArrayList类的泛型等效类并增强了功能,表明对象是可通过索引访问的对象的强类型列表...在.NET 2.0以上可以完全代替ArrayList,就是说ArrayList已经被淘汰...

而动态数组和链表在本质上是不同的...在.NET 2.0以上有双向链表LinkedList <T>泛型类,它也是继承自ICollection <T>,IEnumerable <T>,ICollection,IEnumerable...

能够使用foreach遍历的集合,必须继承IEnumberable(或IEnumerable <T>泛型接口)接口。
IEnumberable接口只有一个方法:
IEnumerator GetEnumberator(){}//返回一个IEnumberator类型的对象,该对象实现System.Collection.IEnumerator接口。
interface IEnumberator
{
object Current{get;}
bool MoveNext();
void Reset();
}
在程序中拼凑sql时,可以这样使用List <T>
List <SqlParameter> list=new List <SqlParameter>();
list.Add(new SqlParameter("参数名","参数值"));
...
SqlParameter[] para=list.ToArray();
C# 中的 `IEnumerable<T>` 是一个泛型接口,定义在 `System.Collections.Generic` 命名空间中。它主要用于表示可以枚举的集合,允许开发者以统一的方式遍历集合中的元素。 ### 基本用法 `IEnumerable<T>` 接口包含一个方法 `GetEnumerator()`,该方法返回一个 `IEnumerator<T>` 类型的对象,用于遍历集合中的元素。通常情况下,`foreach` 循环会自动调用 `GetEnumerator()` 方法来遍历集合。 ```csharp using System; using System.Collections.Generic; public class Example { public static void Main() { List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; foreach (int number in numbers) { Console.WriteLine(number); } } } ``` ### 自定义实现 `IEnumerable<T>` 开发者可以自定义类来实现 `IEnumerable<T>` 接口,以便支持 `foreach` 循环的遍历操作。下面是一个简单的示例: ```csharp using System; using System.Collections; using System.Collections.Generic; public class CustomCollection<T> : IEnumerable<T> { private T[] items; public CustomCollection(T[] items) { this.items = items; } public IEnumerator<T> GetEnumerator() { return new CustomEnumerator<T>(items); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class CustomEnumerator<T> : IEnumerator<T> { private T[] items; private int currentIndex = -1; public CustomEnumerator(T[] items) { this.items = items; } public T Current { get { if (currentIndex < 0 || currentIndex >= items.Length) throw new InvalidOperationException(); return items[currentIndex]; } } object IEnumerator.Current => Current; public void Dispose() { // No resources to dispose } public bool MoveNext() { currentIndex++; return currentIndex < items.Length; } public void Reset() { currentIndex = -1; } } public class Example { public static void Main() { CustomCollection<int> collection = new CustomCollection<int>(new int[] { 1, 2, 3, 4, 5 }); foreach (int item in collection) { Console.WriteLine(item); } } } ``` ### 延迟执行和 `yield` 关键字 `IEnumerable<T>` 的一个强大特性是支持延迟执行。通过使用 `yield` 关键字,可以轻松实现延迟加载的集合。 ```csharp using System; using System.Collections.Generic; public class Example { public static void Main() { foreach (int number in GetNumbers()) { Console.WriteLine(number); } } public static IEnumerable<int> GetNumbers() { yield return 1; yield return 2; yield return 3; yield return 4; yield return 5; } } ``` ### 性能考虑 尽管 `IEnumerable<T>` 提供了极大的灵活性,但在某些情况下需要注意性能问题。例如,多次遍历 `IEnumerable<T>` 可能会导致重复计算,尤其是在处理大型数据集时。为了提高性能,可以将结果缓存到列表中。 ```csharp using System; using System.Collections.Generic; using System.Linq; public class Example { public static void Main() { IEnumerable<int> numbers = GetNumbers().ToList(); // 缓存结果 foreach (int number in numbers) { Console.WriteLine(number); } foreach (int number in numbers) { Console.WriteLine(number); } } public static IEnumerable<int> GetNumbers() { Console.WriteLine("Generating numbers..."); yield return 1; yield return 2; yield return 3; yield return 4; yield return 5; } } ``` ### 相关编程问题 1. **内存泄漏**:不当使用 `IEnumerable<T>` 可能会导致内存泄漏,特别是在使用闭包和匿名函数时。[^3] 2. **延迟执行**:理解延迟执行的概念非常重要,因为它可能会影响程序的行为和性能。 3. **线程安全**:`IEnumerable<T>` 本身不提供线程安全性,因此在多线程环境中需要额外的同步机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值