Jimmy Bogard brought to my attention today that I had been doing something wrong all along. I’ve been using Count() on my enumerations when I should have been using Any(). I’ve even done this in a presentation I’ve been giving the past few months. This is from Mash Up.
if (businesses.Count() == 0)
{
return PartialView("Message", new MessageViewData { Header = "No Results Found",
Message = "We didn't find anything near your location." });
}
else
{
return View(new ResultsViewData { Geolocation = geolocation, Businesses = businesses });
}
The problem, as Jimmy pointed out in his twitter feed, is that Count() iterates the entire enumeration (unless it is an ICollection<T>, via a commenter with Reflector). Any(), on the other hand, will return after it hits the first one. This should be rewritten.
if (businesses.Any())
{
return View(new ResultsViewData { Geolocation = geolocation, Businesses = businesses });
}
else
{
return PartialView("Message", new MessageViewData { Header = "No Results Found",
Message = "We didn't find anything near your location." });
}
The reason I used Count() is quite simple: I was too used to using the Count property on List<T>. I never bothered to look if there was a better way of doing this.
Just as Count() can take a parameter as a predicate, so can Any(). This is useful in that it prevents an unnecessary Where to be chained up.
if (primes.Any(p => primes.Contains(p + 4)) )
{
Console.WriteLine("Prime numbers provided contains Cousin primes");
}
The scenario you should use Count() is when you need to know the actual count.
var cousins = primes.Count(p => primes.Contains(p + 4));
Console.WriteLine("{0} primes provided have cousins", cousins);
Use the method that fits the job. I know I will be paying more attention to Any() from now on.