gpt4 book ai didi

c# - Linq Any() 副作用

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:55 28 4
gpt4 key购买 nike

如果 reflector 是正确的(我倾向于相信它是正确的),这就是 Any() 的实现:

public static bool Any<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
using (IEnumerator<TSource> e = source.GetEnumerator()) {
if (e.MoveNext()) return true;
}
return false;
}

据我了解,MoveNext()将基础枚举器移动一个位置,因此调用 Any()多次会对“缩小”集合产生不利影响。

我试图用 List<> 重现这个但我无法做到这一点,但我无法找出什么 List<>以不同的方式解决这个问题。

我的简单例子来验证List<T>与多个 Any() 一起正常工作调用:

var meh = new List<string> {"1", "2"};
var enumerable = meh.AsEnumerable();
bool any = enumerable.Any(); //true
any = enumerable.Any(); //true
any = enumerable.Any(); //true but isn't it meant to have "moved" the enumerator by two positions already?
any = enumerable.Any(); //true

所以我的问题是:

  1. 我对 Any() 的理解是否正确?确实对 Enumerable 有副作用
  2. 如果是这样,List<> 是如何做到的?规避它?

抱歉,如果这是一个愚蠢的问题。只是一些我发现非常有趣的东西。

最佳答案

由于 using 语句释放了枚举器,所以它总是从头开始。枚举器也总是从 source.GetEnumerator() 创建,不会重复使用。实际上这是 .NET 源代码,如您所见 here .

Any的另一个重载也是如此:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (predicate(element)) return true;
}
return false;
}

它枚举序列直到谓词匹配,然后它就会被释放。

此方法也没有使用延迟执行(它缺少 yield 关键字)。因此它总是立即执行。

关于c# - Linq Any() 副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31556839/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com