I originally posted an extended version of this post on my blog.
It's easy to start working with LINQ to replace for
, foreach
, and other loops.
But, often we make some common mistakes when working with LINQ. Here are three common mistakes we make when working with LINQ for the first time and how to fix them.
Mistake 1: Use Count instead of Any
We should always prefer Any
over Count
to check if a collection has any elements or has at least one element that meets a condition.
Let's write,
movies.Any(); //😀👉
Instead of,
movies.Count() > 0; //😕🫸
The Any
method returns when it finds at least one element, but the Count
method evaluates the entire query. This could be a performance hit for large collections.
Mistake 2: Use Where followed by Any
We can use a condition with Any
directly, instead of filtering first with Where
to then use Any
.
Let's write,
movies.Any(movie => movie.Rating == 5); //😀👉
Instead of,
movies.Where(movie => movie.Rating == 5).Any(); //😕🫸
The same applies to the Where
method followed by FirstOrDefault
, Count
, or any other method that receives a filter condition.
We could use the filter condition directly instead of relying on the Where
method first.
Mistake 3: Use FirstOrDefault without null checking
Let's always check if we have a result when working with FirstOrDefault
, LastOrDefault
, and SingleOrDefault
.
When any of those three methods don't find results, they return the default value of the collection type.
For objects, the default value would be a null
reference. And, do you know what happens when we access a property or method on a null
reference?... Yes, It throws the fearsome NullReferenceException
. Arrggg!
We have this mistake in the following code sample. We forgot to check if the worst
variable has a value. Ooops!
var movies = new List<Movie>
{
new Movie("Titanic", 1998, 4.5f),
new Movie("The Fifth Element", 1995, 4.6f),
new Movie("Terminator 2", 1999, 4.7f),
new Movie("Avatar", 2010, 5),
new Movie("Platoon", 1986, 4),
new Movie("My Neighbor Totoro", 1988, 5)
};
var worst = movies.FirstOrDefault(movie => movie.Rating < 2);
// We forgot to check for nulls after using FirstOrDefault
// It will break 💣💣💣
Console.WriteLine($"{worst.Name}: [{worst.Rating}]");
// 👆👆👆
// System.NullReferenceException: 'Object reference not set to an instance of an object.'
//
// worst was null.
record Movie(string Name, int ReleaseYear, float Rating);
Notice we wrote a LINQ query with FirstOrDefault
looking for the first movie with a rating lower than 2. But, we don't have any movie that matches that condition. The FirstOrDefault
method returned null
and we forgot to check if the worst
variable was different from null
before using it.
An if (worst != null)
would have solved the problem.
There are other alternatives to get rid of the NullReferenceException
when using FirstOrDefault
:
- the DefaultOrEmpty method
- C# 8.0 Nullable reference types
- .NET 6.0 FirstOrDefault with a default value
Voilà ! Those are the three most common LINQ mistakes. I know they seem silly, but we often overlook them.
Want to write more expressive code for collections? Join my Udemy course, Getting Started with LINQ, and master everything you need to work productively with LINQ — all in less than two hours!
Happy coding!
Top comments (2)
Ran a quick benchmark because I was interested in how different the execution times are......wow!!!! Any is far and away the way to go!!!
Thanks Stephen for your comment. Yeah, Any returns as soon as it finds at least one element...Wow, I was planning another post in this series to show precisely that benchmark...