2016-08-22 21 views
4

在执行成员访问之前,我已经知道空条件运算符can be used to test为null。C#6空条件运算符 - 作为代码切换器?

例如:

int? length = customers?.Length; // null if customers is null 
Customer first = customers?[0]; 

如果customerscustomers?.Length为null,则customers?.Length将返回null和null将在int? length = ...可变

我也知道,它可以used单个原子在多线程环境中调用方法:

public void OnFoo() 
{ 
    Foo?.Invoke(this, EventArgs.Empty); 
} 

AFAIU - 如果Foonull然后

Foo?.Invoke(this, EventArgs.Empty); 

同样是null

所以我们留下了

public void OnFoo() 
{ 
    null; //compilation error 
} 

所以我要问:

问题

似乎空条件运算符不仅用于测试空,如果有,那么它进行更深层次的:x?.y?.c?.d -

,但它也像代码切换:

像这样:

public void OnFoo() 
    { 
     Foo?.Invoke(this, EventArgs.Empty); //Let's assume Foo =null; 
    } 

变为

public void OnFoo() 
    { 

    } 

对不起,对吗?我没有找到这方面的任何文件。

回答

6

空条件运算符是一个操作导致的表达 - 它不是一个声明

您的关于Foo?.Invoke(this, EventArgs.Empty)等效于null的逻辑并没有成立,因为它似乎假设了一种不适用的“模板替换”。

类型表达

​​

的是什么,因为Invokevoid返回类型。你不能写:

// Invalid 
var result = Foo?.Invoke(this, EventArgs.Empty); 

这就像在7.6。的C#5规范的5:

评估一个调用表达式如下被分类的结果是:

  • 如果调用表达式调用一个方法或委托返回void,结果是没有。只有在语句表达式(§8.6)或lambda表达式(§7.15)的主体中才允许分类为无表达式的表达式。否则会发生绑定时错误。
  • 否则,结果是由方法或委托返回的类型的值。

甲成员调用可以使用一个空条件运算,在该点时的主要表达式计算为一个非空值时,才执行该调用。涉及空条件运算符的调用表达式的结果与使用常规.运算符时的结果相同,只是如果结果为非空值类型,则带有空条件运算符的结果为相应的可空值类型。

当C#6规范出现时,所有这些都会更精确 - 但我不知道那会是什么时候。 (我不认为认为目前有一个C#6规范,我相信在MS中有一个内部规范,但不是公共规范的一个,因为标准化C#5越来越接近ECMA标准化过程,这可能会影响C#6的发布过程。)

+0

感谢Jon。但是:_ [如果您可以打印它,或者将其分配给一个变量,则它是一个表达式。如果你不能,这是一个声明](https://www.quora.com/Whats-the-difference-between-a-statement-and-an-expression-in-Python)._。因为我不能通过:var result = Foo?.Invoke(this,EventArgs.Empty);' - 然后根据他的链接,它是一个声明。我的错误在哪里? –

+1

@RoyiNamir:这是关于Python,而不是C#,我怀疑它还是过于简化。你的'var result = ...;'不会编译,因为'Invoke'返回'void' ...我不确定你在问什么。 –

+0

Jon - [我在做梦](https://github.com/ljw1004/csharpspec/blob/gh-pages/CSharp%20Language%20Specification.pdf?raw=true)?请参阅第188页 –