IEnumerable.Any(Func)何时返回值?

时间:2012-08-23 21:40:44

标签: c# performance linq lambda ienumerable

我最近在我使用的代码库中看到了一些代码,其中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之前处理每个元素,在这种情况下?

4 个答案:

答案 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”测试遍历整个列表导致异常被抛出。