【问题标题】:Differences in the new syntax of C# 6.0 / New null check syntax?C# 6.0 新语法的区别/新的空检查语法?
【发布时间】:2016-04-27 09:44:29
【问题描述】:

首先,我为这个问题中使用的标题道歉,因为我什至不知道如何问它,也不知道如何搜索它,所以它可能在某个地方,类似于这个的问题一。


我最近在 Visual Studio 2015 上遇到了一个我以前从未见过的潜在修复。在构建EventHandlers 时,我通常会这样做:

public event EventHandler MyEvent;

internal void onMyEvent(EventArgs eventArgs) {
    if(MyEvent != null) {
        MyEvent(this, eventArgs);
    }
}

但现在,Visual Studio 2015 使 if 语句和相应的括号变灰,并且在悬停时显示一条消息,指出可以简化委托调用。简化版如下所示:

public event EventHandler MyEvent;

internal void onMyEvent(EventArgs eventArgs) {
    MyEvent?.Invoke(this, eventArgs);
}

这究竟是如何工作的?如果'?' 之前的表达式为空,是否会因为调用null 之外的方法或代码停止 执行而抛出Exception

另外,我是否可以将检查变量/方法/方法是否为 null 的每个 if 语句替换为“”,而不考虑代码的可读性?


旁注:我假设这是来自 C# 的新版本 6.0,因为我以前从未见过它。如果我错了,请纠正我

【问题讨论】:

  • 又叫空条件运算符
  • 这比我预期的要简单得多。感谢@allan 的帮助。我现在将发布这个问题的答案。
  • FWIW 您调用事件的旧方式并不是最好的——最终订阅者有可能在您检查 null 和调用事件处理程序之间取消订阅,从而导致 NRE。您应该先复制它,然后再检查它是否为空,see the first example here
  • @JamesThorpe 因为我从来没有遇到过使用该代码的问题,所以我从来没有想过这个问题,但是感谢您提供的信息,尽管从现在开始我可能不再需要它了。

标签: c# visual-studio c#-6.0


【解决方案1】:

正如已经指出的那样,这个 C#6 功能称为Null-conditional Operators

还值得研究使用 ILSpy 生成的 C# 代码:

internal void onMyEvent(EventArgs eventArgs)
{
    EventHandler expr_07 = this.MyEvent;
    if (expr_07 != null)
    {
        expr_07(this, eventArgs);
    }
}

如您所见,这是一个纯编译器功能。它只是将您的代码重写为传统的空检查。

回答你的问题(虽然我猜你已经通过查看代码知道了这一点):

不会因为调用方法而引发异常吗 如果 '?' 之前的表达式为 null 或代码停止执行为空?

当您的事件处理程序为空时,不会抛出异常。当 ? 之前的对象时,代码不会被执行为空。

到目前为止,这只是一个方法调用。显然,如果您要分配一个值,该值是使用 Null 条件运算符的表达式的结果,则要复杂一些:如果它是引用类型,则您的变量保持为空,但如果它是值类型,则它将自动为空,并且如果您使用“?”的对象也将为空。运算符为空。

下面是这个案例的反编译代码:

Program.Customer[] array = new Program.Customer[10];
    if (array == null)
    {
        int? arg_33_0 = null;
    }
    else
    {
        Program.Customer expr_1A = array[0];
        if (expr_1A == null)
        {
            int? arg_33_0 = null;
        }
        else
        {
            new int?(expr_1A.IntField);
        }
    }

【讨论】:

  • 你怎么不能MyEvent?(this, eventArgs);That?.WouldBeNice();(如果 That 不是 null 在功能集中,它会在我的开发人员体验中调用 WouldBeNice() :)
  • @toddmo 有趣的一点!我想这会干扰条件运算符。在没有“.”的“?”之前,编译器需要一个布尔值,然后对条件运算符求值。看这段代码: bool b = Decide(); int intVal= b?(1) : 2; (您从 sn-p 中看到了模式:'variable?(') 我不是语言专家,C# 团队的某个人可以回答这个问题,但我认为这就是您需要 '?.'那个案子。
  • MyEvent.?(this, eventArgs); - 如果缺少方法名,使用默认方法名。?.?.?大声笑 idk 要么,但看到这一点我并不感到困惑。只有埃里克知道:)
【解决方案2】:

让事情变得简单......

MyEvent?.Invoke(this, eventArgs);中的?叫做Null Conditional Operator,用来简化代码。

它们用于在调用方法或访问可枚举的索引之前测试 null,例如 ArrayList

这个例子可以在关于 Null Condition Operator 的页面上找到,它是不言自明的:

// null if customers is null
int? length = customers?.Length;

// null if customers is null
Customer first = customers?[0];

// null if customers, the first customer, or Orders is null
int? count = customers?[0]?.Orders?.Count();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多