Ответ 1
Может ли кто-нибудь объяснить мне, зачем нужна скобка?
Потому что Identity()
возвращает Foo
(не a Foo?
) и, следовательно, не имеет свойства Value
. Если Foo
имеет значение NULL, нуль будет распространяться по вызову Identity
.
Когда вы помещаете круглые скобки вокруг него, результаты выражения представляют собой Nullable<Foo>
, который имеет свойство Value
.
Также обратите внимание, что если Foo
равно null, вы будете вызывать Value
на Nullable<Foo>
, который не имеет значения, и получит исключение во время выполнения. Некоторые статические анализаторы признают, что у вас есть возможное исключение для нулевой ссылки, ожидающее появления и предупреждающее вас.
Если вы разложите их на эквиваленты без нулевого распространения, будет более понятно:
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
Если
Identity()
возвращаетFoo
, почемуFoo foo3 = foo?.Identity();
не компилируется?
Эквивалент этого будет:
Foo foo3
if(foo != null)
{
foo3 = foo.Identity();
}
else
{
foo3 = null; // not possible
}