C#中传入同一IEnumerator调用方法为何每次回到初始状态?
问题原因解析
这是因为List<T>.GetEnumerator()返回的是值类型的枚举器(List<T>.Enumerator),而非引用类型的IEnumerator<T>。当你把它作为IEnumerator<int>接口类型的参数传递时,会触发装箱操作——将值类型包装为引用类型对象。
核心问题在于:每次向DoSomethingWith方法传递枚举器时,值类型的枚举器都会被重新装箱,生成一个包含原枚举器副本的新包装对象。这意味着两次调用DoSomethingWith时,实际操作的是两个独立的枚举器副本,每个副本都处于初始状态,因此每次MoveNext()都会指向第一个元素1。
如果要验证这个逻辑,可以提前完成装箱操作,确保两次传递的是同一个引用对象:
List<int> l = [1, 2, 3, 4, 5]; void DoSomethingWith(IEnumerator<int> e) { Console.WriteLine(e.MoveNext()); Console.WriteLine(e.Current); } IEnumerator<int> boxedEnumerator = l.GetEnumerator(); // 提前装箱,仅生成一个包装对象 DoSomethingWith(boxedEnumerator); DoSomethingWith(boxedEnumerator);
此时运行代码会得到你预期的输出:
True 1 True 2
因为现在两次调用操作的是同一个装箱后的枚举器实例,状态会持续更新。
补充说明:如果是返回引用类型枚举器的集合(比如旧的ArrayList),就不会出现这个问题——它们的枚举器本身就是引用类型,传递时不会生成副本。
内容的提问来源于stack exchange,提问作者rabejens
相关产品推荐
相关产品推荐

