这两个接口字面上很相似,其实也有一定的关联。
一个类A实现了IEnumerator,也就是实现Current属性,MoveNext方法,Reset方法。只要实现这些方法,这个类A就可以用foreach这种语法了。
IEnumerable接口主要实现了GetEnumerator方法,该方法返回一个IEnumerator。一个类A实现IEnumerable接口后,调用foreach语法的时候,会自动的调用GetEnumerator方法,然后在这个IEnumerator中遍历。
所以只要实现两者之中任意一个接口,就可以用foreach语法了。但是本质上都是对IEnumerator做foreach,只是一个是直接,一个是间接。
代码说明:比如类baz,实现了IEnumerable,那么下面的代码
foreach (Foo bar in baz){
...
}
说明代码就功能上等同于下面的代码
IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current()
...
}
---------------------
如果一个类,同时实现了IEnumerator<T>,IEnumerable<T>,那么就是糟糕的设计
因为用foreach语法的时候,会先调用IEnumerable的GetEnumerator方法。这是经过测试的。
测试代码如下:
class Class1 : IEnumerator<string>,IEnumerable<string>
{
public int count = 0;
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return null;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return null;
}
///////////////////////////////////////////
string IEnumerator<string>.Current
{
get { return DateTime.Now.ToString(); }
}
void IDisposable.Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get { return DateTime.Now; }
}
bool System.Collections.IEnumerator.MoveNext()
{
if (count < 10)
{
count++;
return true;
}
else
{
return false;
}
}
void System.Collections.IEnumerator.Reset()
{
count=0;
}
}
---------------main.cs---------
Class1 c = new Class1();
foreach (var i in c)
{
Console.WriteLine(i);
}
本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/619269 ,如需转载请自行联系原作者