LINQ语句之间的区别

Jvi*_*hes 3 c# linq c#-4.0

有什么区别

FirstOrDefault(someField => someField.Name.Equals(settings.Text))
Run Code Online (Sandbox Code Playgroud)

Where(someField => someField.Name.Equals(settings.Text)).FirstOrDefault() 
Run Code Online (Sandbox Code Playgroud)

据我所知,在这两种情况下,Linq将一直运行到第一次出现这种情况.

Jen*_*sen 9

他们两个陈述的结果是一样的.您可以将第一个视为第二个的较短版本.

FirstOrDefault方法有一个带有第二个参数的重载,Func<TSource, bool>它与您在Where语句中定义的谓词相同.


Ser*_*kiy 6

如果我们谈论Linq to Objects,那么有一个显着的区别.第二个声明

Where(someField => someField.Name.Equals(settings.Text)).FirstOrDefault() 
Run Code Online (Sandbox Code Playgroud)

将在WhereEnumerableIterator内部创建,然后它将开始枚举并获取第一项:

// argument checks and collection optimizations removed
public static IEnumerable<TSource> Where<TSource>(
     this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
     // it enumerates source and returns items which match predicate
     return new WhereEnumerableIterator<TSource>(source, predicate);
}

public static TSource First<TSource>(this IEnumerable<TSource> source)
{
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())        
            return enumerator.Current;        
    }

    throw Error.NoElements();
}
Run Code Online (Sandbox Code Playgroud)

但是第一个语句将从源代码中获取与谓词匹配的第一个项目,而不创建额外的枚举器:

// argument checks removed
public static TSource First<TSource>(
    this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{    
    foreach (TSource local in source)
    {
        if (predicate(local))        
            return local;        
    }

    throw Error.NoMatch();
}
Run Code Online (Sandbox Code Playgroud)

所以,第一个在性能方面更好:

FirstOrDefault(someField => someField.Name.Equals(settings.Text))
Run Code Online (Sandbox Code Playgroud)