我在这里读过Eric 关于foreach枚举的文章以及foreach可以工作的不同场景
为了防止旧的C#版本进行装箱,C#团队为foreach启用了鸭子类型,以便在非Ienumerable集合上运行.(GetEnumerator返回具有公共MoveNext和Current属性的东西的公共就足够了.
所以,埃里克写了一个样本:
class MyIntegers : IEnumerable
{
public class MyEnumerator : IEnumerator
{
private int index = 0;
object IEnumerator.Current { return this.Current; }
int Current { return index * index; }
public bool MoveNext()
{
if (index > 10) return false;
++index;
return true;
}
}
public MyEnumerator GetEnumerator() { return new MyEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
Run Code Online (Sandbox Code Playgroud)
但我相信它有一些错别字(在Current属性实现中缺少get访问器)阻止它编译(我已经通过电子邮件发送给他了).
无论如何 …
我想要一个从A < char > 继承并实现IEnumerable < string > 的便利包装器B.
public class A<T> : IEnumerable<T[]>
{
public IEnumerator<T[]> GetEnumerator()
{
return Enumerate().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
protected IEnumerable<T[]> Enumerate()
{
throw new System.NotImplementedException();
}
}
public class B : A<char>, IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
return Enumerate().Select(s => new string(s)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)现在,这完全正常,foreach变量类型被推断为字符串:
B b = new B();
foreach (var s in b) …Run Code Online (Sandbox Code Playgroud) 如果我将for-each循环传入方法参数,如果我将该参数作为一个IEnumerable或者如果我将该参数作为一个传递,那么是否有任何好处或差别List?
我在代码库中遇到了这个问题:
foreach (var evtType in EventLocator.GetTypes())
Run Code Online (Sandbox Code Playgroud)
并且记住Shlemiel画家的算法会EventLocator.GetTypes()在每个循环上调用该方法还是只调用一次?