Foreach缓存是可枚举的吗?
本文关键字:枚举 缓存 Foreach | 更新日期: 2023-09-27 18:01:58
假设SomeMethod
具有签名
public IEnumerable<T> SomeMethod<T>();
foreach (T tmp in SomeMethod<T>()) { ... }
和
IEnumerable<T> result = SomeMethod<T>();
foreach (T tmp in result) { ... }
换句话说,SomeMethod<T>
的结果是在第一个语句中缓存,还是在每次迭代时求值?
假设你在谈论c#。
foreach
翻译成这样:
var enumerable = SomeMethod<T>(); // Or whatever is passed to foreach
var enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
...
}
因此,由于enumerable
只需要一次,即使您将其直接放入foreach
语句中,也只会有一次对someemethod的调用。
enumerATOR通常是不同于enumerABLE的对象类型。通常,枚举数将保存对可枚举对象的引用,以及关于该对象在枚举过程中的位置的一些信息。可枚举对象的目的实际上不是提供一个项目序列,而是提供一个枚举数,该枚举数将反过来提供该序列。
在vb.net和c#中,foreach构造的工作方式是在对象上调用一次GetEnumerator方法并抓取它返回的对象,在从GetEnumerator返回的对象上重复调用MoveNext和Current,最后,如果该对象实现了Dispose,则对其调用Dispose。c#和vb.net实际上都没有缓存可枚举对象,但是在调用一次GetEnumerator之后,它们都不需要出于任何目的使用该对象。这两种语言都保留了枚举数,但都没有提供任何使用它做任何事情的方法,除了对MoveNext、Current和Dispose的隐含调用。