问题
What difference between
FirstOrDefault(someField => someField.Name.Equals(settings.Text))
and
Where(someField => someField.Name.Equals(settings.Text)).FirstOrDefault()
?
As far as I understand in both cases Linq will run till the first occurence that suits the condition.
回答1:
If we are talking about Linq to Objects, then there is one notable difference. Second statement
Where(someField => someField.Name.Equals(settings.Text)).FirstOrDefault()
Will create WhereEnumerableIterator
internally, and then it will start enumeration and take first item:
// 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();
}
But first statement will just take first item from source which matches predicate without creating additional enumerator:
// 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();
}
So, first one is better in terms of performance:
FirstOrDefault(someField => someField.Name.Equals(settings.Text))
回答2:
They result of both statements is the same. You can think of the first one as a shorter version of the second one.
The FirstOrDefault
method has an overload taking in a second parameter, a Func<TSource, bool>
which is the same predicate you are defining in your Where
statement.
来源:https://stackoverflow.com/questions/20394023/difference-between-linq-firstordefault-vs-where-firstordefault