我最近在我使用的代码库中看到了一些代码,其中ReSharper提供将其重构为collection.Any(Func< bool >)
。
我想知道这对性能的影响。假设我有一个看起来像这样的电话:
bool hasEvenValue = collection.Any(i => (i % 2) == 0);
......以及看起来像这样的数据......
{ 1, 2, 3, 5, 3, 5, 1, 3, 5, 2 }
Enumerable.Any()什么时候返回值?第二个数据元素,或者它会在返回true之前处理每个元素,在这种情况下?
答案 0 :(得分:5)
一看到匹配的元素就会返回,如果没有,它会处理整个序列。
因此,它比使用.Count(...) != 0
更好(也更具可读性和语义意义)。
答案 1 :(得分:2)
以下是IEnumerable<T>.Any(...)
的实现(未使用dotKeep编译):
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 source1 in source)
{
if (predicate(source1))
return true;
}
return false;
}
所以基本上只要项目满足条件就会返回。
答案 2 :(得分:1)
IEnumerable.Any(Func)何时返回值?
执行时始终立即执行,因为它不会延迟执行。它返回一个布尔值,表示序列中元素之一是否为给定谓词返回true。因此,与Count
不同,它不需要执行整个查询。
答案 3 :(得分:1)
这是我在LINQPad中编写的一些代码,用于说明Any
运算符在第一次匹配后终止。
void Main()
{
Console.WriteLine("Are there any evens? " + YieldEvenThenThrowEnumerable().Any(i => i % 2 == 0));
Console.WriteLine("still running");
Console.WriteLine("Are there any odds? " + YieldEvenThenThrowEnumerable().Any(i => i % 2 == 1));
Console.WriteLine("never reaches this point");
}
IEnumerable<int> YieldEvenThenThrowEnumerable()
{
yield return 2;
throw new InvalidOperationException("TEST");
}
哪个输出:
有没有平均值? 真
仍在运行中 &LT;此时,可枚举引发InvalidOperationException&gt;
如果测试“if any are even”的第一个Any
调用遍及整个可枚举,则程序将终止而不显示任何消息。第二个调用是为了说明“if any are odd”测试遍历整个列表导致异常被抛出。