Sorry for this awkward example, but I want to keep it as to the point as possible
Lets say, I have parsed a json-file, which gives me the hierarchy below
var customers = myObj.SubObj?.CustomerList.EmptyIfNull();
var plusCustomers = customers.Where(...) // Resharper warning
myobj cannot be null SubObject can be null sometimes
I have an extension method
IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> enumerable) => enumerable ?? Enumerable.Empty<T>();
So I expect the plusCustomers-line to be safe(empty list instead of null). But I get a warning
possible "null"assignment to a non-nullable entity
If I replace the first line with
var customers = myObj.SubObj.CustomerList.EmptyIfNull();
I get rid of the warning, but that is not correct. How can I convince Resharper that this is ok?...or I'm I mistaken?
CodePudding user response:
You can add brackets:
(myObj.SubObj?.CustomerList).EmptyIfNull();
The effect of the null chaining (?.
) is to evaluate the whole chain of member accesses to null, if the LHS operand is null, rather than evaluating just that single member access to null. For example, consider a long chain of member accesses a.b.c.d.e.f
. If only a
is nullable, you would only need to write ?
after a
for this to be safe. It doesn't just evaluate a?.b
to null if a
is null, because in that case you'd have to write ?
after every member access for this to be safe, and that's a bit annoying.
So without the brackets, the whole member access is made nullable due to ?.
, regardless of what you call at the end.
By adding brackets, you break up the chain of member accesses, so that myObj.SubObj?.CustomerList
is of a nullable type, and calling EmptyIfNull
on that works as expected - returning whatever type EmptyIfNull
should return.