Enumerable.FirstOrDefault()在找到项目时停止吗?

时间:2013-05-15 06:28:15

标签: c# vb.net linq ienumerable

我尝试在MSDN,SO和网络上搜索,但找不到答案。

说我有一个我做FirstOrDefault()的集合。我们说它找到了这个项目。它是停止并返回该项目还是继续搜索并阻碍性能?

4 个答案:

答案 0 :(得分:6)

如果您对此仍然含糊不清,.NET框架中的源代码是从here实现的:

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    IList<TSource> list = source as IList<TSource>;
    if (list != null) {
        if (list.Count > 0) return list[0];
    }
    else {
        using (IEnumerator<TSource> e = source.GetEnumerator()) {
            if (e.MoveNext()) return e.Current;
        }
    }
    return default(TSource);
}

public static TSource FirstOrDefault<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 element;
    }
    return default(TSource);
}

显然,如果成立,它将会停止

答案 1 :(得分:1)

FirstOrDefault将迭代,直到找到该元素,并且只有在找不到它时才需要迭代整个IEnumerable

答案 2 :(得分:1)

停止并返回。

以下是相关的反编译代码(适用于FirstOrDefault()FirstOrDefault(predicate)

[__DynamicallyInvokable]
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
  if (source == null)
    throw Error.ArgumentNull("source");
  IList<TSource> list = source as IList<TSource>;
  if (list != null)
  {
    if (list.Count > 0)
      return list[0];
  }
  else
  {
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
      if (enumerator.MoveNext())
        return enumerator.Current;
    }
  }
  return default (TSource);
}

它的作用是检查它是否实现IList,如果是,则返回第一个项目(如果有的话)。如果没有,它会获得一个枚举器并尝试执行MoveNext。如果成功,则返回Enumerator.Current。否则它只返回类型(TSource

的默认值
[__DynamicallyInvokable]
public static TSource FirstOrDefault<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 source1;
  }
  return default (TSource);
}

在这里,它首先检查所有args不是null,然后是foreaches,直到找到与谓词匹配的项,然后返回它。如果没有,则只返回该类型的默认值。

(如果您想知道如何获取源代码,我使用dotPeek。这是一个很棒的工具!)

答案 3 :(得分:0)

我希望它能......但是这里有几种说法:

  1. 测试一下。制作一个大集合(这需要很长时间才能搜索),并在开头放置想要查找的元素,然后放在最后。这两个测试所用的时间应该不同,第一个应该更短。

  2. 查看.Net source,亲眼看看。