static void Main(string[] args)
{
List<int> listArray = new List<int>();
listArray.Add(100);
foreach (int item in listArray)
Console.WriteLine(item);
}
Run Code Online (Sandbox Code Playgroud)
a)在foreach声明中呼吁listArray's IEnumerable<int>.GetEnumerator()实现,它通过调用它listArray.GetEnumerator()或IEnumerable<int>.GetEnumerator()或 IEnumerable.GetEnumerator()?
b)同样,当foreach引用对象返回时listArray's IEnumerable<int>.GetEnumerator(),它是通过引用IEnumerator还是IEnumerator<int>引用类型引用该对象?
谢谢
编辑:
我的一些问题将引用此文:
o使用标识符GetEnumerator对类型X执行成员查找,而不使用类型参数.如果成员查找不产生匹配,或者产生歧义,或产生不是方法组的匹配,请检查可枚举接口,如下所述.如果成员查找产生除方法组或不匹配之外的任何内容,建议发出警告.
o使用生成的方法组和空参数列表执行重载解析.如果重载决策导致没有适用的方法,导致歧义,或导致单个最佳方法但该方法是静态的或不公开的,请检查可枚举的接口,如下所述.如果重载决策产生除明确的公共实例方法或没有适用的方法之外的任何内容,建议发出警告.
o如果GetEnumerator方法的返回类型E不是类,结构或接口类型,则会产生错误,并且不会采取进一步的步骤.
o在E上执行成员查找,标识符为Current,没有类型参数.如果成员查找不产生匹配,则结果是错误,或者结果是除允许读取的公共实例属性之外的任何内容,产生错误并且不执行进一步的步骤.
o成员查找在E上执行,标识符为MoveNext,没有类型参数.如果成员查找不产生匹配,则结果是错误,或者结果是除方法组之外的任何内容,产生错误并且不执行进一步的步骤.
o使用空参数列表对方法组执行重载分辨率.如果重载决策导致没有适用的方法,导致歧义,或导致单个最佳方法但该方法是静态的或非公共的,或者其返回类型不是bool,则产生错误并且不采取进一步的步骤.
o集合类型为X,枚举器类型为E,元素类型为Current属性的类型.
否则,检查一个可枚举的接口:o如果只有一个类型T,从而存在从X到接口System.Collections.Generic.IEnumerable的隐式转换,那么集合类型就是这个接口,枚举器类型就是接口System.Collections.Generic.IEnumerator,元素类型为T.
否则,如果存在多个这样的类型T,则产生错误并且不采取进一步的步骤.
否则,如果存在从X到System.Collections.IEnumerable接口的隐式转换,则集合类型为此接口,枚举器类型为接口System.Collections.IEnumerator,元素类型为object.
否则,将产生错误,并且不会采取进一步的步骤.
1)
引自Eric Lippert:
选项(1)是正确的.请注意,这意味着返回的枚举器是一个未装箱的可变结构.
事实上,这是一个可变的结构,如果你做一些愚蠢的事情,比如传递结构,就像它是一个引用类型一样,它具有非常实际的效果; 它将按值复制,而不是通过引用复制.
来自http://en.csharp-online.net/ECMA-334:_15.8.4_The_foreach_statement:
foreach(V v in x)嵌入式语句
然后扩展到:
Run Code Online (Sandbox Code Playgroud){ E e = ((C)(x)).GetEnumerator(); try { V v; while (e.MoveNext()) { …
c# ×1