Foreach Cache IEnumerable吗?

Use*_*ser 5 c# ienumerable

假设SomeMethod有签名

public IEnumerable<T> SomeMethod<T>();
Run Code Online (Sandbox Code Playgroud)

两者之间有什么区别吗?

foreach (T tmp in SomeMethod<T>()) { ... }
Run Code Online (Sandbox Code Playgroud)

IEnumerable<T> result = SomeMethod<T>();

foreach (T tmp in result) { ... }
Run Code Online (Sandbox Code Playgroud)

换句话说,结果SomeMethod<T>是缓存在第一个语句上还是会在每次迭代时进行评估?

Fra*_*čik 13

假设你在谈论C#.

foreach 翻译成这样的东西:

var enumerable = SomeMethod<T>(); // Or whatever is passed to foreach
var enumerator = enumerable.GetEnumerator();

while (enumerator.MoveNext())
{
...
}
Run Code Online (Sandbox Code Playgroud)

因此,enumerable只需要一次,即使您将其直接放入foreach语句中,也只会调用SomeMethod .

  • 我知道代码是为了说明而设计的,但是很多人都没有意识到创建实现IDisposable的枚举器的代码必须**为了正确性*,确保在枚举器上调用Dispose.所有需要确保正确性的是在枚举器的创建周围添加"使用"块. (3认同)
  • 轻微的狡辩:应该有一个"使用"或"最后"块来确保如果枚举器实现IDisposable,它将被处理掉.有许多场景,特别是涉及迭代器,被遗弃的枚举器可能会导致严重的问题. (2认同)
  • @supercat:你是对的,但这个例子只是为了展示 foreach 的主要概念,而不是在生产中使用。foreach 本身将负责处理枚举器。 (2认同)