Reputation: 408
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
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 crashesans2
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
attemptans3
passes because neither ToList
or FirstOrDefault
are ever called. ans3
is set to null as soon as C# discovers list
is nullYou 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