空条件运算符

时间:2017-03-31 14:01:44

标签: c# .net null-conditional-operator

  

var a = b?.c.d;

该表达式是否总是会出现编译错误?如果b为null,则传播null值,因此c也将为null,因此也需要此运算符。据我所知,在表达式中使用此运算符会传播病毒。

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

4 个答案:

答案 0 :(得分:4)

操作员只是语法糖:

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

为什么这会引发编译错误我不清楚。

  

如果b为null,则传播空值,因此c也将为null,因此也需要此运算符

这不是真的。实际上当b为空时c甚至不存在,因为没有该成员可以存在的实例。因此,简而言之,操作员只需返回null,并且不再评估c甚至d

答案 1 :(得分:0)

如果nullb,此运算符会短路并返回null

答案 2 :(得分:0)

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

这就是那句话在旧方式中的样子,?.运算符在它之前的内容为空时看起来不是更深,它只返回null,但是你会在{{{{{{ 1}}已定义但b,因为您没有写为b.c == null

答案 3 :(得分:0)

请注意:

var a1 = b?.c.d;

完全不同于:

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

简单地解释一元运算符?.如何工作(是的,一元!)并不是一件容易的事。但是,如果?.之前的表达式为空,则会跳过“操作”的“链”的其余部分。

因此对于a1,只要d恰好发生Nullable<>,就会得到成员b(或必要的b)所携带的编译时类型的null是空的。如果b.c.d恰好为非空,则与b.c相同,如果a2为空,则可能会失败。

b完全不同。如果(b?.c)为空,它将始终爆炸,因为括号.将是空引用,下一个NullReferenceException运算符将导致c。 (我假设b?.c.d在编译时具有引用类型。)

所以不要认为有一种“左联结”使(b?.c).d等同于 #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #include <unistd.h> #include <iostream> #include <cstring> #include <stdlib.h> #include <stdio.h> main(){ string answer= "Nothing, actually" FILE* fd; if ((fd = fopen("result.txt", "r")) != NULL); static const long max_len = 55 + 1; char buf[max_len + 1]; fseek(fd, -max_len, SEEK_END); ssize_t len = fread(fd, buf, max_len); buf[len] = '\0'; char *last_newline = strrchr(buf, '\n'); char *last_line = last_newline+1; answer= last_line;}

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