使用LINQ where(lamdaexp).First和First(lambdaexp)

han*_*uma 3 c# linq lambda

以下两种方法有什么不同吗?我得到相同的输出,但我试图了解哪个是正确和有效的

方法1:

Product product12 = products.Where(p => p.ProductID == 12).First();
Run Code Online (Sandbox Code Playgroud)

方法2:

Product prod12 = products.First(p => p.ProductID == 12);
Run Code Online (Sandbox Code Playgroud)

Far*_*yev 7

(我假设您正在使用Linq来.Net)
首先让我们看看它们的源代码:

这是Where():

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null) 
        throw Error.ArgumentNull("source");
    if (predicate == null) 
        throw Error.ArgumentNull("predicate");
    if (source is Iterator<TSource>) 
        return ((Iterator<TSource>)source).Where(predicate);
    if (source is TSource[]) 
        return new WhereArrayIterator<TSource>((TSource[])source, predicate);
    if (source is List<TSource>) 
        return new WhereListIterator<TSource>((List<TSource>)source, predicate);
    return new WhereEnumerableIterator<TSource>(source, predicate);
}
Run Code Online (Sandbox Code Playgroud)

这是 First()

   public static TSource First<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;
            }
            throw Error.NoMatch();
        }
Run Code Online (Sandbox Code Playgroud)

让我们找到每个代码的作用:

  1. products.First(p => p.ProductID == 12);

基于First()我们可以说的源代码,First()将迭代收集,并且当它找到符合条件的集合中的第一个项目时将停止迭代.

  1. products.Where(p => p.ProductID == 12).First();

首先,它将在Where方法中创建迭代器,其中元素符合条件.然后,它将再次添加获取该迭代器的第一个元素.并且,一旦发现第一个元素,它将再次返回.

另外,LINQ 在某些方法中使用延迟执行.它与你的问题的结果有一些关系.

延迟执行是执行模型的模式,通过该模式,CLR确保仅在基于IEnumerable的信息源需要时才提取值.当任何Linq运算符使用延迟执行时,CLR将相关信息(例如原始序列,谓词或选择器(如果有))封装到迭代器中,当使用ToList从原始序列中提取信息时将使用该迭代器.方法或ForEachmethod或在C#中手动使用底层的GetEnumerator和MoveNext方法.

而且,问题是.哪一个更快?


重点是,Where().First比...更快First.在List和的情况下Array.否则,First()会更快.以下是@Akash Kava答案的详细说明.

让我们关注Where()实施.WhereListIterator()如果您的集合是List,它将返回,但First()只会迭代源.在我看来,他们已经加快了实施的速度WhereListIterator.在此之后,我们调用First()方法,该方法不接受谓词作为输入,只会迭代过滤集合.

此外,据我所知,Where迭代器避免了间接虚表调用,而是直接调用迭代器的方法.而且,这就是加速的原因.