【问题标题】:What does "object is enumerated" mean in C#?C#中的“对象被枚举”是什么意思?
【发布时间】:2021-10-15 07:57:47
【问题描述】:

我最近一直在阅读有关延迟执行、LINQ、一般查询等的文章和文档,并且经常出现“枚举对象”这一短语。有人可以解释枚举对象时会发生什么吗?

例如article

这个方法是通过延迟执行来实现的。立即返回值是一个存储执行操作所需的所有信息的对象。此方法表示的查询不会执行直到枚举对象直接调用其 GetEnumerator 方法或使用 Visual C# 中的 foreach

【问题讨论】:

  • 它在接下来的几句话中告诉你:直接调用它的GetEnumerator方法或使用foreach
  • 它还告诉你在它enumerated之后将是iterable
  • 假设对象是一个通用项目列表List<TItem>。它已经实现了IEnumerable<T> 接口。为什么我们的查询需要枚举?当我们枚举它时,这个列表到底发生了什么变化?
  • 枚举时列表中没有任何变化。枚举是访问列表的一种方式。索引到列表中将是另一种方式。有些集合甚至没有索引器,只能被认为是项的序列,这就是 IEnumerable 所代表的。枚举的意思是“我现在要将这个集合作为一个项目序列来访问,因为它符合我当前的目标”。
  • FYI 这是 foreachList 编译后所做的事情。

标签: c# .net linq ienumerable deferred-execution


【解决方案1】:

枚举的一般说明

IEnumerable 是一个接口,通常由 C# 中的集合类型实现。例如ListQueueArray

IEnumerable 提供了一个方法GetEnumerator,它返回一个IEnumerator 类型的对象。

IEnumerator 基本上表示集合中元素的“向前移动指针”。 IEnumerator 有:

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

每当执行foreach 循环时,都会检索IEnumerator 并为每次迭代调用MoveNext。您在循环头中定义的变量用IEnumeratorCurrent 填充。


编译一个foreach循环

感谢@Llama

这段代码...

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

不能保证 foreach 会导致 GetEnumerator 实际被调用 - 但是对于编译器来说这是很常见的事情。


报价

此方法表示的查询直到对象才被执行 通过直接调用其 GetEnumerator 方法或 在 Visual C# 中使用 foreach。

基本上它已经告诉你一切。我认为混乱只是来自缺乏对枚举的了解。只要有人调用GetEnumerator,就会执行该方法。只要您将对象放入foreach 循环,就会自动调用GetEnumerator

【讨论】:

  • 我想我的问题很清楚——为什么我们需要枚举我们的数据源对象以及在这个枚举过程中到底发生了什么。你回答得很好,谢谢。不过,我不了解 cmets,答案在我的示例文章中是不言而喻的,或者我不了解延迟执行,问题仅与枚举本身有关。再次感谢。
【解决方案2】:

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

延迟执行:当您编写 LINQ 查询时,它只会在您实际访问结果时执行 - 延迟到您运行代码以迭代结果,即使用 foreach 进行迭代。这是默认行为。

立即执行:我们可以通过在查询中附加 ToList() 或类似方法来强制执行此操作(您会在 C# 代码中经常看到)。

【讨论】:

猜你喜欢
  • 2011-06-25
  • 2013-07-27
  • 2017-01-27
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
相关资源
最近更新 更多