linq 在C#中,“对象被枚举”是什么意思?

biswetbf  于 2022-12-15  发布在  C#
关注(0)|答案(2)|浏览(135)

我最近阅读了一些关于延迟执行、LINQ、一般查询等的文章和文档,经常会出现“对象被枚举”这句话。有人能解释一下当一个对象被枚举时会发生什么吗?
例如article
此方法是使用延迟执行实现的。立即返回值是存储执行操作所需的所有信息的对象。直到通过直接调用其GetEnumerator方法或在Visual C#中使用foreach枚举对象后,才会执行此方法表示的查询

yb3bgrhw

yb3bgrhw1#

枚举的一般说明

IEnumerable是一个接口,在C#中通常用集合类型实现,例如ListQueueArray
IEnumerable提供了一个方法GetEnumerator,它返回一个IEnumerator类型的对象。
IEnumerator基本上表示指向集合中元素的“向前移动指针”。IEnumerator具有:

  • 属性Current,返回当前指向的对象(例如,集合中的第一个对象)。
  • 方法MoveNext,它将指针移动到下一个元素。调用它后,Current将保存对集合中下一个对象的引用。如果集合中没有更多的元素,MoveNext将返回false

每当在IEnumerable上执行foreach循环时,IEnumerator通过GetEnumerator被检索,并且每次迭代都调用MoveNext-直到它最终返回false。您在循环头中定义的变量将用IEnumeratorCurrent填充。

编译foreach循环

感谢@美洲驼
这个密码...

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();
}

引用

在通过直接调用对象的GetEnumerator方法或在Visual C#中使用foreach枚举该对象之前,不会执行此方法表示的查询。
GetEnumerator是自动调用的,例如,当你把你的对象放入一个foreach循环中时,当然,其他函数,例如Linq查询,也可以从你的集合中检索IEnumerator,通过显式(调用GetEnumerator)或隐式的方式,就像我在上面的例子中所做的那样。

z9smfwbn

z9smfwbn2#

我认为您只需要很好地理解LINQ查询的延迟执行与立即执行。

延期执行:当你写一个LINQ查询时,它只在你实际访问结果时执行--直到你运行代码来迭代结果,例如foreach。这是默认行为。
立即执行:我们可以通过在查询中附加一个ToList()或类似的方法来强制执行(这在C#代码中很常见)。

相关问题