Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Where(condition).Any() and Any(condition) equivalent

Tags:

c#

linq

About half of the examples I see for Linq queries using the Any method do so by applying it to the results of a Where() call, the other half apply it directly to the collection. Are the two styles always equivalent, or are there cases wheres that they could return different results?

My testing supports the former conclusion; but edge cases aren't always easy to find.

List<MyClass> stuff = GetStuff();
bool found1 = stuff.Where(m => m.parameter == 1).Any();
bool found2 = stuff.Any(m => m.parameter == 1);
like image 903
Dan Is Fiddling By Firelight Avatar asked Sep 23 '11 18:09

Dan Is Fiddling By Firelight


2 Answers

It comes down to 2 important questions:

  • is it a standard "Where"/"Any" (such as Enumerable.* or Queryable.*), or is it custom? (if the latter, all bets are off)
  • if it is Queryable.*, what is the provider?

The latter matters hugely. For example, LINQ-to-SQL and LINQ-to-EF behave differently re Single, so I would not assume that they behave identically for Any. A more esoteric provider could do anything. But more: LINQ-to-SQL does different things (re the identity-manager) for Single(predicate) vs Where(predicate).Single (and for First too). In fact, there are 3 different behaviours available in LINQ-to-SQL there depending on 3.5, 3.5SP1, or 4.0.

Additionally, IIRC LINQ-to-ADO.NET-Data-Services had different (opposite, from memory) support to EF - so (again from memory) while one provider only supported Single(predicate), the other only supported Where(predicate).Single(); it is not a great leap to suggest that Any() could be similarly affected by different providers.

So: while Any(predicate) and Where(predicate).Any() are semantically equivalent - it is impossible to say if they are actually the same without very detailed information to the context.

like image 123
Marc Gravell Avatar answered Oct 13 '22 00:10

Marc Gravell


Logically, no difference, but performance wise the latter:

stuff.Any(m => m.parameter == 1);

is more performant than:

stuff.Where(m => m.parameter == 1).Any();

because the former does not use an iterator (yield return) to produce it's result. The Where() clause does, iterators are nice, but they do add extra processing overhead.

Is it huge? No, but typically I'd go with the most concise and readable expression for both performance and maintainability.

like image 31
James Michael Hare Avatar answered Oct 12 '22 23:10

James Michael Hare