C# · 12月 30, 2021

c# – List.Enumerator的Reset方法的行为

以下两种方法(一种使用IEnumerator< int>和其他用途List< int> .Enumerator)即使看起来相同也产生不同的结果. static void M1(){ var list = new List<int>() { 1,2,3,4 }; IEnumerator<int> iterator = list.GetEnumerator(); while (iterator.MoveNext()) { Console.Write(iterator.Current); } iterator.Reset(); while (iterator.MoveNext()) { Console.Write(iterator.Current); }}static void M2(){ var list = new List<int>() { 1,4 }; //Here the iterator will be List<int>.Enumerator (which is a struct) var iterator = list.GetEnumerator(); while (iterator.MoveNext()) { Console.Write(iterator.Current); } //This will not work,as Reset method was implemented explicitly //iterator.Reset(); //So casting it to IEnumerator is required //which will lead to @R_721_2419@ing and other issues of struct and interface ((IEnumerator<int>)iterator).Reset(); //Following loop will NOT work while (iterator.MoveNext()) { Console.Write(iterator.Current); }}

有几个问题清楚地解释了这个行为,你可以检查他们here,here和here.

我还有以下两个疑问

>为什么List.Enumerator不会为重置抛出“NotSupportedException”?
>为什么重置被明确地实现,而不是隐含地像MoveNext和Current?

解决方法

Why List.Enumerator does not throw “NotSupportedException” for Reset?

因为微软没有时间机器可以预见5年后会发生什么.类型推论背后的强大动力是林克,在20世纪90年代末,仿制药首次被处理时,它不在路线图上.拳击问题根本就不是一个问题.

Why Reset was implemented explicitly and not implicitly like MoveNext and Current?

因为您不能取消继承接口方法,您只能隐藏它.那个IEnumerator有一个Reset()方法是另一个时间机器问题,这是在1995年设计COM Automation时决定的.选择与后果之间又一个5年的差距:) .NET必须在COM iterators和.NET迭代器之间提供一个体面的映射,以便有机会被采纳.

从链接可以看出,COM迭代器中的另一个功能是克隆.这是ICloneable界面背后的动力,.NET中另一个非常麻烦的界面.那个人在他们的通用兄弟里面实施太麻烦了,只有非通用的收集枚举器实现它.

微软的工作艰巨,每一个设计决策都是他们永远生活的决定.我们很容易,我们可以根本不用Reset