I would like to devote today's article to 4 expressions that you have probably used more than once when writing queries using LINQ. I'm talking about First, FirstOrDefault, Single and SingleOrDefault. Admit it, do you really know in which situations which of these expressions should be used? Or do you tend to use the same thing over and over again in every situation? In this article, you will learn exactly what the differences are between them and in what situations it is best to use them.
Example
I have prepared a simple list on which we will test these expressions:
var numbers = new List<int> { 12, 42, 1, 10, 12 };
We will check 2 different scenarios for each expression. We are interested in such cases:
1) Retrieving values from a list when several numbers meet a condition.
2) Retrieving a value from a list when the number you are looking for does not exist in the list.
First()
var firstValueWhen2Match = numbers.First(x => x == 12);
Console.WriteLine(firstValueWhen2Match);//12
var firstValueWhenDoesntExists = numbers.First(x => x == 0); //System.InvalidOperationException
Console.WriteLine(firstValueWhenDoesntExists);
1) If there are more values matching the condition, when you use First(), only the first one will be returned and this ends the further search of the list.
2) If First() does not find any value that meets the condition, a System.InvalidOperationExeption exception will be thrown.
FirstOrDefault()
var firstOrDefaultValueWhen2Match = numbers.FirstOrDefault(x => x == 12);
Console.WriteLine(firstOrDefaultValueWhen2Match);//12
var firstOrDefaultValueWhenDoesntExists = numbers.FirstOrDefault(x => x == 0);
Console.WriteLine(firstOrDefaultValueWhenDoesntExists);//0
1) If there are more than one value matching the condition, when you use FirstOrDefault(), only the first one will be returned and this ends the further search.
2) If FirstOrDefault() does not find any value that meets the condition, the default value will be returned, in this case 0.
Single()
var singleValueWhen2Match = numbers.Single(x => x == 12);//System.InvalidOperationException
Console.WriteLine(singleValueWhen2Match);
var singleValueWhenDoesntExists = numbers.Single(x => x == 0);//System.InvalidOperationException
Console.WriteLine(singleValueWhenDoesntExists);
1) If there are more values that meet the condition, a System.InvalidOperationExeption exception will be thrown using Single().
2) If Single() does not find any value that meets the condition, a System.InvalidOperationExeption exception will be thrown.
SingleOrDefault()
var singleOrDefaultValueWhen2Match = numbers.SingleOrDefault(x => x == 12);//System.InvalidOperationException
Console.WriteLine(singleOrDefaultValueWhen2Match);
var singleOrDefaultValueWhenDoesntExists = numbers.SingleOrDefault(x => x == 0);
Console.WriteLine(singleOrDefaultValueWhenDoesntExists);//0
1) If there are more values that meet the condition, a System.InvalidOperationExeption exception will be thrown using SingleOrDefault().
2) If SingleOrDefault() does not find any value that meets the condition, then the default value will be returned, in this case 0.
In what situations should you use which expressions?
1) If you know that there should be only one record (single) satisfying a given condition and there cannot be more than one, then you should use Single() or SingleOrDefault() - depending on whether you expect an exception or a default value, when there is no record that meets the condition.
2) If you are only interested in the first record (first) that meets the condition and it doesn't matter to you that there may be more records that meet this condition, you should use First() or FirstOrDefault() - depending on whether you expect an exception or default value when there is no record that meets the condition.
3) Also remember that First() and FirstOrDefault() are faster than Single() and SingleOrDefault() because once the first value is found, further searching of the collection is finished.
SUMMARY
In this short but very important article, I introduced you to the basic differences between 4 popular LINQ expressions. Remember that not all of them are suitable for every situation. Try to choose appropriate expressions depending on the situation. Also remember that recruiters often ask during job interviews about the basic differences between these expressions, so I hope you won't be surprised by such a question anymore :)