Could anyone explain to me why the parenthesis are needed?
Because Identity()
returns a Foo
(not a Foo?
) and thus has no Value
property. If foo
is null, the null will propagate through the Identity
call.
When you put parentheses around it, the results of the expression is a Nullable<Foo>
which does have a Value
property.
Also note that if foo
is null, then you will be calling Value
on a Nullable<Foo>
that has no value, and will get an exception at run-time. Some static analyzers will recognize that you have a possible null-reference exception waiting to happen and warn you.
If you expand them to their equivalents without null-propagation it will be more clear:
Foo foo1;
if(foo != null)
{
foo1 = foo.Identity().Value; // not possible - Foo has no Value property.
}
else
{
foo1 = null; // also not possible
}
Foo foo2;
Foo? temp;
if(foo != null)
{
temp = foo.Identity();
}
else
{
temp = null; // actually a Nullable<Foo> with no value
}
foo2 = temp.Value; // legal, but will throw an exception at run-time if foo is null
If
Identity()
returnsFoo
, why doesFoo foo3 = foo?.Identity();
not compile ?
The equivalent of that would be:
Foo foo3
if(foo != null)
{
foo3 = foo.Identity();
}
else
{
foo3 = null; // not possible
}