看看这段代码:
public class myWords : IEnumerable<string>
{
string[] f = "I love you".Split(new string[]{"lo"},StringSplitOptions.RemoveEmptyEntries);
public IEnumerator<string> GetEnumerator()
{
return f.Select(s => s + "2").GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return f.Select(s => s + "3").GetEnumerator();
}
}跑步:
myWords m = new myWords();
foreach (var s in m)
{
Console.WriteLine(s);
}产量
I 2
ve you2 // notice "2", so the generic Ienumerator has executed.据我所知,非通用IEnumerator版本是为了兼容性.
问题:
IEnumerator运行?发布于 2015-02-02 19:20:36
其他的回答有点漏掉了重点。
如果foreached的编译时类型有一个名为GetEnumerator的非泛型非静态方法,则接口根本不重要,该方法采用零参数。(此方法的返回类型可以是任何类型,泛型或非泛型:接口不重要。)
因此,调用第一个方法的原因是,这是public方法。
你可以改变这一点:
public class myWords : IEnumerable<string>
{
string[] f = "I love you".Split(new string[]{"lo"},StringSplitOptions.RemoveEmptyEntries);
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return f.Select(s => s + "2").GetEnumerator();
}
public IEnumerator GetEnumerator()
{
return f.Select(s => s + "3").GetEnumerator();
}
}要证明不需要接口,请尝试如下:
public class myWords // no interfaces!
{
string[] f = "I love you".Split(new string[]{"lo"},StringSplitOptions.RemoveEmptyEntries);
public IEnumerator GetEnumerator()
{
return f.Select(s => s + "3").GetEnumerator();
}
}但是,实现IEnumerable<>是明智的。然后,您的类型可以与Linq (IEnumerable<>上的扩展方法)一起使用,并且可以用作其他只需要IEnumerable<>的方法的参数。
此外,明智的做法是让返回非泛型IEnumerator的方法(或显式接口实现)直接调用返回IEnumerator<>的方法(或显式接口实现)。有两个不同的返回序列确实令人困惑(但是对于询问和回答事情是如何工作的问题来说,这是很好的)。
发布于 2013-02-16 10:38:46
当代码将类转换到非泛型接口时,将执行非泛型IEnumerator:
((IEnumerable)myWords).GetEnumerator(); // this calls the non-generic one如果您将类传递给某些需要非泛型IEnumerator的遗留函数,则这主要是相关的。
因此,如果您有一个包含函数的库,并且将类传递给这个函数,它将使用非泛型IEnumerator。
DoSomeStuffWithAnIEnumerable(IEnumerable x)
{
var foo = x.GetEnumerator();
// or, as stackx said, an example with foreach:
foreach (var foo2 in x)
Console.WriteLine(foo2);
}
DoSomeStuffWithAnIEnumerable(new myWords());请注意,简单地使用泛型IEnumerator实现非泛型是完全有效的:
public class myWords : IEnumerable<string>
{
....
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}这样你就可以确定它们都有相同的效果。
发布于 2013-02-16 10:47:04
IEnumerable的非泛型版本是通过显式接口实现实现的。这意味着您只能通过转换到接口来调用显式实现的函数。
之所以显式实现IEnumerable,是因为除了返回类型之外,方法签名是相同的。
将myWords显式转换为IEnumerable允许您调用非通用版本,如:(IEnumerable)myWords。
C#指南解释了这是如何工作的:显式接口实现。
https://stackoverflow.com/questions/14909326
复制相似问题