List<int> a = new List<int>();
foreach (var val in a)
{
var b = 1 + val;
}
被编译器转换成如下形式:
List<int> list = new List<int>();
List<int>.Enumerator enumerator = list.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int current = enumerator.Current;
int num = 1 + current;
}
} finally {
((IDisposable)enumerator).Dispose();
}
2条答案
按热度按时间yb3bgrhw1#
枚举的一般说明
IEnumerable
是一个接口,在C#中通常用集合类型实现,例如List
、Queue
或Array
。IEnumerable
提供了一个方法GetEnumerator
,它返回一个IEnumerator
类型的对象。IEnumerator
基本上表示指向集合中元素的“向前移动指针”。IEnumerator
具有:Current
,返回当前指向的对象(例如,集合中的第一个对象)。MoveNext
,它将指针移动到下一个元素。调用它后,Current
将保存对集合中下一个对象的引用。如果集合中没有更多的元素,MoveNext
将返回false
。每当在
IEnumerable
上执行foreach
循环时,IEnumerator
通过GetEnumerator
被检索,并且每次迭代都调用MoveNext
-直到它最终返回false
。您在循环头中定义的变量将用IEnumerator
的Current
填充。编译foreach循环
感谢@美洲驼
这个密码...
被编译器转换成如下形式:
引用
在通过直接调用对象的GetEnumerator方法或在Visual C#中使用foreach枚举该对象之前,不会执行此方法表示的查询。
GetEnumerator
是自动调用的,例如,当你把你的对象放入一个foreach
循环中时,当然,其他函数,例如Linq查询,也可以从你的集合中检索IEnumerator
,通过显式(调用GetEnumerator
)或隐式的方式,就像我在上面的例子中所做的那样。z9smfwbn2#
我认为您只需要很好地理解LINQ查询的延迟执行与立即执行。
延期执行:当你写一个LINQ查询时,它只在你实际访问结果时执行--直到你运行代码来迭代结果,例如
foreach
。这是默认行为。立即执行:我们可以通过在查询中附加一个
ToList()
或类似的方法来强制执行(这在C#代码中很常见)。