为什么C#在表达式中使用nullables时需要括号?

Luk*_*s92 33 c# nullable

我是C#的新手,在探索语言功能时,我遇到了一些奇怪的事情:

struct Foo
{
    public Foo Identity() { return this; }

    public static void Bar(Foo? foo)
    {
        Foo foo1 = foo?.Identity().Value; // Does not compile
        Foo foo2 = (foo?.Identity()).Value; // Compiles
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释为什么需要括号?

D S*_*ley 40

任何人都可以向我解释为什么需要括号?

因为Identity()返回a Foo(不是a Foo?)因此没有Value属性.如果foo为null,则null将通过Identity调用传播.

当你把它周围括号,则结果表达Nullable<Foo>确实有一个Value属性.

还要注意的是,如果foo 零,那么你将被调用ValueNullable<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
Run Code Online (Sandbox Code Playgroud)

如果Identity()返回Foo,为什么不Foo foo3 = foo?.Identity();编译?

相当于:

Foo foo3
if(foo != null)
{
    foo3 = foo.Identity();
}
else
{
    foo3 = null;  // not possible 
}
Run Code Online (Sandbox Code Playgroud)