Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirstOrDefault returns NullReferenceException if no match is found

Tags:

c#

lambda

Here is my code:

string displayName = Dictionary.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID)).Value.DisplayName; 

The code works fine if x.Value.ID matches options.ID. However, I get a NullReferenceException if it doesn't.

like image 434
Raz Mahato Avatar asked Jan 16 '14 12:01

Raz Mahato


People also ask

What does FirstOrDefault return if not found?

The major difference between First and FirstOrDefault is that First() will throw an exception if there is no result data for the supplied criteria whereas FirstOrDefault() returns a default value (null) if there is no result data.

How do I know if FirstOrDefault is null?

LINQ check if FirstOrDefault is null and use it Just call .... Any(a => a. DateReturned == null)... to check whether there are any items that meet the condition.... If you only want to check the latest assignment, add ....Take(1)...

What is the default value returned by FirstOrDefault?

The default value for reference and nullable types is null . The FirstOrDefault method does not provide a way to specify a default value. If you want to specify a default value other than default(TSource) , use the DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource) method as described in the Example section.

What is the difference between FirstOrDefault and find?

The key thing to notice here is that FirstOrDefault is called on Enumerable whereas Find is called as a method on the source list. So it's iterating over an array of items which makes sense, since a list is a wrapper on an array.


2 Answers

FirstOrDefault returns the default value of a type if no item matches the predicate. For reference types that is null. Thats the reason for the exception.

So you just have to check for null first:

string displayName = null; var keyValue = Dictionary     .FirstOrDefault(x => x.Value.ID == long.Parse(options.ID)); if(keyValue  != null) {     displayName = keyValue.Value.DisplayName; }  

But what is the key of the dictionary if you are searching in the values? A Dictionary<tKey,TValue> is used to find a value by the key. Maybe you should refactor it.

Another option is to provide a default value with DefaultIfEmpty:

string displayName = Dictionary     .Where(kv => kv.Value.ID == long.Parse(options.ID))     .Select(kv => kv.Value.DisplayName)   // not a problem even if no item matches     .DefaultIfEmpty("--Option unknown--") // or no argument -> null     .First();                             // cannot cause an exception 
like image 79
Tim Schmelter Avatar answered Oct 23 '22 17:10

Tim Schmelter


You can use a combination of other LINQ methods to handle not matching condition:

var res = dictionary.Where(x => x.Value.ID == someID)                     .Select(x => x.Value.DisplayName)                     .DefaultIfEmpty("Unknown")                     .First(); 
like image 44
Konrad Kokosa Avatar answered Oct 23 '22 16:10

Konrad Kokosa