2

我最近在我使用的代码库中看到了一些代码,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

4 回答 4

5

它一看到匹配的元素就返回,或者如果没有,它会处理整个序列。

出于这个原因,它比使用更好.Count(...) != 0(也更具可读性和语义意义)。

于 2012-08-23T21:43:07.537 回答
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;
}

所以基本上只要项目满足条件,它就会返回。

于 2012-08-23T21:45:00.293 回答
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");
}

哪个输出:

有没有偶数?
真正的
仍在运行
<此时从可枚举中抛出 InvalidOperationException >

如果Any测试“如果有偶数”的第一个调用遍历整个可枚举,则程序将终止而不显示任何消息。第二次调用是为了说明“如果有奇数”测试遍历整个列表,导致异常被抛出。

于 2012-08-26T02:18:48.213 回答
1

IEnumerable.Any(Func) 什么时候返回值?

总是在它被执行时立即立即执行,因为它没有被延迟执行。它返回一个布尔值,指示序列中的元素之一是否对给定谓词返回 true。因此它不需要执行整个查询,不像Count.

于 2012-08-23T21:44:17.300 回答