2017-03-31 129 views
4

var a = b?.c.d;无条件运算符

这个表达式不应该总是给出编译错误吗?如果b为null,则通过传播null值,所以c也将为null,因此也需要此运算符。根据我的理解,在表达式中使用此运算符会传播病毒。

但是,Visual Studio 2015和Resharper都没有对我说什么,我在这里错过了什么吗?

+0

为什么会出现编译器错误?如果'b'为空,则表达式计算为空。如果不是,则表达式返回'b.c.d'的结果。 –

+1

不,如果'b'已经为空,'c'根本就没有被评估,使'a'简单地为'null'。 – HimBromBeere

+0

我不明白这个问题;如果'b'是'null',则表达式不会被评估为furter,而是产生'null',所以'c'不会有任何事情发生。 – Codor

回答

4

运营商只是为这个语法糖:

MyType a = b == null ? 
    null: 
    b.c.d; 

这是为什么抛出编译错误我不清楚。

如果b为null,null值是通过所以C传播也将是零,因此也需要这种操作

这isn't如此。其实当b为空c甚至不存在,因为没有该成员可以存在的实例。因此,简而言之,操作员只需返回null并省略任何进一步评估c甚至d

+0

这不是一个有效的转换。 'a'总是被分配一个新值,尽管该值可能是'null'。 – Servy

+0

'var a =(b == null)? null:b.c.d;' –

+0

@Servy你是对的,我编辑得适当。 – HimBromBeere

0

该操作员确实发生短路,并在bnull的情况下返回null

0
var a = b == null ? null : b.c.d 

这是该语句是什么样子的老方式,?.操作者不看的更深一些的时候是什么之前,它是空的,它只是返回null,你会然而得到一个错误的位置b是但由于您没有写为var a = b?.c?.d,所以定义为b.c == null

0

需要注意的是:

var a1 = b?.c.d; 

是完全不同的:

var a2 = (b?.c).d; 

这不是很容易解释在短期如何单目运算符?.作品(是的,一元!)。但是想法是,如果?.之前的表达式为空,则“运算”的“链”的其余部分将被跳过。

所以对于a1,你得到的成员d(或必要时该类型的Nullable<>)进行编译时类型每当b恰好是空的空。当b恰好非空时,与b.c.d相同,如果b.c为空,则可能会失败。

但是a2是完全不同的。如果b为空,它总是会炸毁,因为括号(b?.c)将为空引用,并且下一个.运算符将导致NullReferenceException。 (我在这里假设c在编译时有一个引用类型。)

所以不要认为有一种“左结合”,使b?.c.d等于(b?.c).d


您可以在this answer in another thread中找到初步C#语言规范的链接;他们在第7.7.1节中提到空条件运算符作为一元运算符。