gpt4 book ai didi

c# - foreach如何调用GetEnumerator()?通过 IEnumerable 引用还是通过...?

转载 作者:行者123 更新时间:2023-12-03 02:48:32 25 4
gpt4 key购买 nike

    static void Main(string[] args)
{
List<int> listArray = new List<int>();
listArray.Add(100);
foreach (int item in listArray)
Console.WriteLine(item);
}

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 Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.

o Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.

o If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.

o Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.

o Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.

o Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.

o The collection type is X, the enumerator type is E, and the element type is the type of the Current property.

  • Otherwise, check for an enumerable interface: o If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator, and the element type is T.

  • Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.

  • Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.

  • Otherwise, an error is produced and no further steps are taken.

1)

引用埃里克·利珀特的话:

Option (1) is correct. Note that this means that the enumerator returned is an unboxed mutable struct.

The fact that this is a mutable struct has very real effects if you do something foolish like passing around the struct as though it were a reference type; it will be copied by value, not by reference.

来自http://en.csharp-online.net/ECMA-334:_15.8.4_The_foreach_statement :

foreach (V v in x) embedded-statement

is then expanded to:

{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}

The variable e is not visible to or accessible to the expression x or the embedded statement or any other source code of the program.

如果是listArray ,返回的枚举数被保存(即它的值被保存)在变量 e 中(因此变量 e 是一个可变结构)。但是根据上面的摘录, e我的源代码无法访问,那么我如何能够传递这个结构(除非我编写代码手动执行 foreach 语句自动执行的操作)?

2)

Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.

看来如果我们实现GetEnumerator在类 ( X ) 本身中,则 Current也应该在类( E )本身中实现(因此 E 不应该显式实现 Current ),因为编译器不会费心检查 IEnumerator<T> / IEnumerator 。在成员查找(在 E 上使用标识符 Current )不产生匹配的情况下的接口(interface)?

3)

If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator, and the element type is T.

根据上述,如果foreach必须检查 IEnumerable<T>接口(interface),然后foreach将始终使用 IEnumerator<T> Current 的版本?因此,如果E显式实现IEnumerator<T> Current 的版本如果它还实现了 Current 的另一个版本在类(class)本身中, foreach永远会打电话IEnumerable<T> Current 的版本?

4)

The GetEnumerator method is documented as returning one of these:

http://msdn.microsoft.com/en-us/library/x854yt9s.aspx

其中一个(复数形式)是什么意思?您提供的链接显示GetEnumerator (由 List<T> 实现)仅返回 struct类型。

5)

g. The collection type is X, the enumerator type is E, and the element type is the type of the Current property

也许是一个无用的问题 - 根据上面的说法,foreach不检查某些用户定义集合实际存储的元素类型,而是假设元素类型与 Current 返回的类型相同属性(property)?

最佳答案

foreach 的行为在语言规范第 8.8.4 节中有详细说明。简而言之

foreach(表达式中的T t)

  • 如果表达式是一个数组*,则使用 IEnumerable 接口(interface)(*请参阅下面 Eric Lippert 的评论。)
  • 否则,如果表达式具有 GetEnumerator 方法,则使用该方法
  • Else if 表达式可转换为IEnumerable<T> ,使用该界面和 IEnumerator<T> (以及相关方法)
  • Else if 表达式可转换为IEnumerable ,使用该界面和 IEnumerator (以及相关方法)

还有各种错误情况和我正在掩盖的事情。但是,简而言之,如果您的集合是通用的,它将采用通用界面选项。

关于c# - foreach如何调用GetEnumerator()?通过 IEnumerable 引用还是通过...?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3679805/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com