IEnumerable或者IEnumerable< T >接口
IEnumerable
和 IEnumerable<T>
是C#中的两个非常重要的接口,用于表示可以被遍历的集合。它们是.NET框架中集合和序列的基础接口,广泛用于LINQ(Language Integrated Query)和其他集合操作。1. IEnumerable
接口
IEnumerable
是一个非泛型接口,表示可以被遍历的集合。它定义了一个方法 GetEnumerator
,用于获取一个枚举器(IEnumerator
),该枚举器可以用来逐个访问集合中的元素。定义
csharp
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
示例代码
csharp
using System;
using System.Collections;
public class MyCollection : IEnumerable
{
private int[] _items;
public MyCollection(int[] items)
{
_items = items;
}
public IEnumerator GetEnumerator()
{
foreach (var item in _items)
{
yield return item;
}
}
}
class Program
{
static void Main(string[] args)
{
MyCollection collection = new MyCollection(new int[] { 1, 2, 3, 4, 5 });
foreach (var item in collection)
{
Console.WriteLine(item);
}
}
}
输出结果
1
2
3
4
5
2. IEnumerable<T>
接口
IEnumerable<T>
是一个泛型接口,表示可以被遍历的集合,其中的元素类型为 T
。它继承自 IEnumerable
,并定义了一个泛型版本的 GetEnumerator
方法。定义
csharp
public interface IEnumerable<out T> : IEnumerable
{
new IEnumerator<T> GetEnumerator();
}
示例代码
csharp
using System;
using System.Collections;
using System.Collections.Generic;
public class MyCollection<T> : IEnumerable<T>
{
private T[] _items;
public MyCollection(T[] items)
{
_items = items;
}
public IEnumerator<T> GetEnumerator()
{
foreach (var item in _items)
{
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
MyCollection<int> collection = new MyCollection<int>(new int[] { 1, 2, 3, 4, 5 });
foreach (var item in collection)
{
Console.WriteLine(item);
}
}
}
输出结果
1
2
3
4
5
3. IEnumerable
和 IEnumerable<T>
的区别
-
类型安全:
-
IEnumerable<T>
是泛型接口,提供了类型安全的枚举器IEnumerator<T>
,避免了类型转换的需要。 -
IEnumerable
是非泛型接口,返回的枚举器是IEnumerator
,需要进行显式类型转换。
-
-
继承关系:
-
IEnumerable<T>
继承自IEnumerable
,因此任何实现了IEnumerable<T>
的集合也隐式地实现了IEnumerable
。
-
-
使用场景:
-
IEnumerable<T>
通常用于需要类型安全的场景,如LINQ查询。 -
IEnumerable
通常用于需要兼容非泛型集合的场景。
-
4. IEnumerable
和 IEnumerable<T>
的实现
-
GetEnumerator
方法:-
IEnumerable
的GetEnumerator
方法返回一个IEnumerator
。 -
IEnumerable<T>
的GetEnumerator
方法返回一个IEnumerator<T>
。
-
-
IEnumerator
和IEnumerator<T>
:-
IEnumerator
是非泛型接口,提供了Current
属性和MoveNext
方法。 -
IEnumerator<T>
是泛型接口,提供了类型安全的Current
属性和MoveNext
方法。
-
5. 使用 IEnumerable
和 IEnumerable<T>
-
LINQ查询:
-
IEnumerable<T>
是LINQ查询的基础接口,支持各种查询操作,如Where
、Select
、OrderBy
等。
-
csharp
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 使用LINQ查询
IEnumerable<int> evenNumbers = numbers.Where(x => x % 2 == 0);
foreach (var number in evenNumbers)
{
Console.WriteLine(number); // 输出:2, 4
}
}
}
-
集合操作:
-
IEnumerable
和IEnumerable<T>
提供了丰富的集合操作方法,如Count
、Any
、All
等。
-
csharp
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 检查集合是否包含偶数
bool hasEven = numbers.Any(x => x % 2 == 0);
Console.WriteLine(hasEven); // 输出:True
// 获取集合中的最大值
int maxNumber = numbers.Max();
Console.WriteLine(maxNumber); // 输出:5
}
}
6. 注意事项
-
延迟执行:
-
IEnumerable
和IEnumerable<T>
的操作通常是延迟执行的,即只有在遍历集合时才会真正执行查询。 -
如果需要立即执行查询,可以使用
ToList
或ToArray
等方法。
-
-
性能:
-
IEnumerable<T>
提供了类型安全的访问,避免了不必要的类型转换,因此在性能上通常优于IEnumerable
。
-
-
兼容性:
-
如果需要兼容非泛型集合,可以使用
IEnumerable
,但建议尽量使用IEnumerable<T>
以获得更好的类型安全性和性能。
-
7. 总结
IEnumerable
和 IEnumerable<T>
是C#中用于表示可遍历集合的两个重要接口。IEnumerable<T>
是泛型版本,提供了类型安全的枚举器,而 IEnumerable
是非泛型版本,适用于需要兼容非泛型集合的场景。通过合理使用这两个接口,可以实现高效的集合操作和LINQ查询。