C#6空条件运算符 - 作为代码转换器?

Roy*_*mir 4 c# c#-6.0 null-conditional-operator

我已经知道在执行成员访问之前,可以使用 null条件运算符 来测试 null.

例如 :

 int? length = customers?.Length; // null if customers is null 
 Customer first = customers?[0];
Run Code Online (Sandbox Code Playgroud)

如果customers为null customers?.Length ,则customers?.Length 返回null,这null将是int? length = ...变量

我也知道它可以用于多线程环境中方法调用的单个原子操作:

public void OnFoo()
{
    Foo?.Invoke(this, EventArgs.Empty);
}
Run Code Online (Sandbox Code Playgroud)

AFAIU - 如果Foo是的null

 Foo?.Invoke(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)

也是 null

所以我们离开了

public void OnFoo()
{
    null; //compilation error
}
Run Code Online (Sandbox Code Playgroud)

所以我问:

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

但它也像代码切换一样:

像这样:

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

  public void OnFoo()
    {

    }
Run Code Online (Sandbox Code Playgroud)

我对吗?我没有找到任何相关方面的文档.

Jon*_*eet 6

null条件运算符是一个运算符,它产生一个表达式 - 它不是一个语句.

关于Foo?.Invoke(this, EventArgs.Empty)等价的逻辑null确实不成立,因为它似乎假设了一种不适用的"模板替换".

表达式的类型

Foo?.Invoke(this, EventArgs.Empty)
Run Code Online (Sandbox Code Playgroud)

什么都没有,因为Invoke有一个void返回类型.你不能写:

// Invalid
var result = Foo?.Invoke(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)

这与C#5规范的7.6.5类似:

评估调用表达式的结果分类如下:

  • 如果invocation-expression调用返回的方法或委托void,则结果为空.被分类为空的表达式仅允许在statement-expression(第8.6节)的上下文中或作为lambda表达式的主体(第7.15节).否则会发生绑定时错误.
  • 否则,结果是方法或委托返回的类型的值.

成员调用可以使用空条件运算符,此时仅在主表达式求值为非空值时执行调用.涉及null条件运算符的调用表达式的结果与使用常规.运算符的结果相同,只是如果结果是非可空值类型,则使用null条件运算符的结果是相应的可空值类型.

当然,当C#6规范问世时,所有这些都将更精确地展现出来 - 但我不知道什么时候会出现这种情况.(我不认为目前有一个C#6规范.我确信MS内部有一个,但不是公开的.随着ECMA标准化过程越来越接近标准化C#5,这可能会影响发布C#6的过程.)