通用列表<>在哪里?实施重置?

时间:2015-08-10 08:45:28

标签: list c#-4.0 ienumerable enumerator

当我转到List&lt;&gt;的定义时我可以看到它有一个公共结构Enumerator,它实现了接口IEnumerator<T>,IDisposable和IEnumerator。

IEnumerator应该强制执行Reset - 除了Current和MoveNext。然而,只实现了Current和MoveNext。 怎么会这样? 我在哪里可以找到List&lt;&gt ;?的重置()

var list = new List<int>();
list.Add(23);
list.Add(44);
var Enumerator = list.GetEnumerator();
while (Enumerator.MoveNext())
{
    Console.WriteLine(Enumerator.Current);
}
Enumerator.

当我在代码中尝试时,没有重置():
好的 - 我试图显示截图,但他们不允许我 但是复制上面的代码后,在Enumerator的 Dot-operator(。)之后没有显示Reset-Method。

有人会知道并对此有所了解吗?

我看到它调用IEnumerator的重置,这是mscorlib的一部分。

var list = new List<int>();
list.Add(23);
list.Add(44);
var Enumerator = list.GetEnumerator();
Enumerator.MoveNext();
Enumerator.MoveNext();
Console.WriteLine(Enumerator.Current);
((IEnumerator<int>)Enumerator).Reset();
Enumerator.MoveNext();

然而,因为IEnumerator是一个界面,它怎么能被它调用呢? IEnumerator中的Reset()应该只是一个定义,并且实现留给使用该接口的任何人 但不知何故,这里仅通过定义要实现的接口来提供实际功能。在任何地方我都看不到实际的实现 - 那部分我不明白。

2 个答案:

答案 0 :(得分:4)

explicitly implementedas shown in the documentationIEnumerator.Current。换句话说,您只能在编译时类型为IEnumerator的值上调用该方法。

所以你可以使用:

// Casing changed to be more conventional
var enumerator = list.GetEnumerator();
((IEnumerator)enumerator).Reset();

然而,无论如何,那将会打值(因为List<T>.Enumerator是一个结构),这将使它毫无意义。目前尚不清楚您是否只对Reset方法明显缺乏感兴趣,但总的来说,我强烈建议您依赖{{1 - 它经常没有实现,IMO它不应该成为界面的一部分......

答案 1 :(得分:1)

您认为您正在使用IEnumerator&lt;&gt;界面,但你不是。类型推断越来越好,Enumerator变量的类型实际上是 List.Enumerator&lt;&gt;,一种结构类型。使用界面,你就没有问题了:

    IEnumerator<int> Enumerator = list.GetEnumerator();
    while (Enumerator.MoveNext()) {
        Console.WriteLine(Enumerator.Current);
    }
    Enumerator.Reset();  // Fine

它不适用于List.Enumerator&lt;&gt;因为Microsoft故意通过将其设为私有来隐藏Reset()方法实现。注意其他集合类(如Dictionary和HashSet)的迭代器也是如此。

可以使用解释。 IEnumerator封装了一个只有前向的迭代器,是Linq之家建立的基础。 Reset()方法是一个问题,不再是严格前向的。您将迭代器移回。在实践中,您会发现在许多情况下尝试调用Reset()会产生NotImplementedException。列表不是问题,很容易回去。 Linq的大问题。

IEnumerator 设计时没有Reset()方法。但这并不是.NET设计师的选择,这在1996年之前就已经确定,早在任何人开始研究.NET之前。迭代器是COM Automation中的现有概念。这是Visual Basic版本4的扩展模型,它取代了16位VBX模型。

广受欢迎,Windows上的几乎所有语言运行库都实现了它。并且仍然在.NET程序中使用得非常多。在大多数情况下巧妙地隐藏,例如,当您在Web上放置WebBrowser时,无法告诉您正在使用它。 .NET设计人员也被迫实现它,以便让程序员转向.NET。也是非常麻烦的ICloneable接口的来源。