saravanan
saravanan

Reputation: 408

C# nullable and FirstOrDefault failure

I have a null list and attempting a FirstOrDefault behaves differently in different coding styles. Trying to undersand the difference. The below three snippets attempt the same thing. But ans3 alone works without any exception. Aren't ans2 and ans3 the same?

        IList<int> list = null;

        var ans1 = list.FirstOrDefault(); //Fails

        var temp = list?.ToList();
        var ans2 = temp.FirstOrDefault(); //Fails

        var ans3 = list?.ToList().FirstOrDefault(); //Passes
        

Upvotes: 0

Views: 467

Answers (1)

Caius Jard
Caius Jard

Reputation: 74710

Aren't ans2 and ans3 the same?

They aren't: The null conditional operator ?. halts the left-to-right evaluation of a chained sequence at the first null it encounters and resolves the whole expression to null

  • ans1 fails because you call a method on a null. This crashes
  • ans2 fails because list is null, the ?. sees that it is null and resolves the expression to null (ToList() is never called) so null is stored in temp. You then try and call FirstOrDefault on a null temp, which crashes for the same reason as the ans1 attempt
  • ans3 passes because neither ToList or FirstOrDefault are ever called. ans3 is set to null as soon as C# discovers list is null

You could use ?? in combiantion with ?. to ensure that items have a value:

var temp = list?.ToList() ?? new List<Thing>();

If ?. inspects list and finds it to be null, then the list?.ToList() resolves to null. ?? will then act, ensuring that the expression resolves to an empty List instead. This would be safe to call methods on..

Null conditional can be used more than once:

ans3 = someObject?.Any?.Of()?.These?.PropsOrMethods?.Could()?.Be?.Null

If any property or method in that chain returned null, the whole thing is null as soon as thenull is encountered, no matter where it was in the chain. If the null thing was These, then nothing after it would be called

Upvotes: 8

Related Questions