在C#的编程体系中,IEnumerable和IEnumerator是两个和迭代逻辑紧密相关的核心接口,它们共同支撑了集合遍历、foreach循环等常见功能的实现,理解两者的区别和联系是掌握C#集合操作的基础。

IEnumerable接口介绍
IEnumerable接口位于System.Collections命名空间下,它的核心作用是标识一个对象是可以被迭代的,也就是可以被foreach循环遍历。该接口只定义了一个方法:
// IEnumerable接口的核心方法定义
public interface IEnumerable
{
// 返回一个IEnumerator迭代器对象
IEnumerator GetEnumerator();
}只要一个类实现了IEnumerable接口,就意味着这个类可以被迭代,调用它的GetEnumerator方法就能拿到对应的迭代器,后续就可以通过迭代器逐个访问集合中的元素。
IEnumerator接口介绍
IEnumerator接口同样是System.Collections命名空间下的接口,它是具体的迭代器实现,负责维护迭代的状态,提供访问当前元素和移动到下一个元素的能力。它的定义包含三个核心成员:
public interface IEnumerator
{
// 获取当前迭代位置的元素
object Current { get; }
// 将迭代位置移动到下一个元素,返回true表示移动成功,false表示已经到末尾
bool MoveNext();
// 重置迭代位置到起始点之前
void Reset();
}迭代器的工作流程是:初始时位置在第一个元素之前,调用MoveNext方法移动到第一个元素,此时Current属性返回第一个元素;再次调用MoveNext就移动到下一个元素,直到MoveNext返回false,说明已经遍历完所有元素。
两者的联系与区别
两者的核心关联是:IEnumerable是迭代能力的标识,它负责对外提供IEnumerator迭代器;而IEnumerator是具体的迭代执行者,负责实际的遍历逻辑。简单说就是,IEnumerable告诉外界我可以被遍历,IEnumerator负责完成具体的遍历动作。
常见区别如下:
- IEnumerable是集合层面的接口,一个可迭代的集合只需要实现一次该接口即可
- IEnumerator是迭代器层面的接口,每次开始迭代都会生成一个新的IEnumerator实例,各自维护自己的迭代状态,互不干扰
- IEnumerable的方法只有GetEnumerator,而IEnumerator需要维护Current、MoveNext、Reset三个核心逻辑
自定义实现示例
下面我们自定义一个简单的字符串集合类,同时实现IEnumerable和IEnumerator接口,展示两者的配合使用:
using System;
using System.Collections;
// 自定义可迭代的字符串集合类,实现IEnumerable接口
public class MyStringCollection : IEnumerable
{
private string[] _data = { "第一个元素", "第二个元素", "第三个元素" };
// 实现IEnumerable的GetEnumerator方法,返回对应的迭代器
public IEnumerator GetEnumerator()
{
return new MyStringEnumerator(_data);
}
// 嵌套类实现IEnumerator接口,负责具体的迭代逻辑
private class MyStringEnumerator : IEnumerator
{
private string[] _items;
private int _position = -1; // 初始位置在第一个元素之前
public MyStringEnumerator(string[] items)
{
_items = items;
}
// 实现Current属性,返回当前位置的元素
public object Current
{
get
{
if (_position < 0 || _position >= _items.Length)
{
throw new InvalidOperationException("迭代位置无效");
}
return _items[_position];
}
}
// 实现MoveNext方法,移动位置到下一个元素
public bool MoveNext()
{
_position++;
return _position < _items.Length;
}
// 实现Reset方法,重置位置到起始点
public void Reset()
{
_position = -1;
}
}
}
// 测试代码
class Program
{
static void Main()
{
MyStringCollection collection = new MyStringCollection();
// foreach循环会自动调用GetEnumerator获取迭代器,然后循环调用MoveNext和Current
foreach (var item in collection)
{
Console.WriteLine(item);
}
// 也可以手动使用迭代器遍历
IEnumerator enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
}运行上述代码,两种方式都会依次输出三个字符串元素,这也验证了IEnumerable和IEnumerator的配合逻辑。实际开发中我们很少需要手动实现这两个接口,因为C#的泛型版本IEnumerable<T>和IEnumerator<T>更常用,而且yield关键字可以简化迭代器的编写,但理解这两个基础接口的原理,能帮助我们更好地掌握C#的迭代机制。
C#IEnumerableIEnumerator迭代器修改时间:2026-06-07 01:03:08