这两行之间有区别吗?

MyName = (s.MyName == null) ? string.Empty : s.MyName

要么
MyName = s.MyName ?? string.Empty

最佳答案

更新:我写了一篇博客文章,更深入地讨论了这个主题。 http://www.codeducky.org/properties-fields-and-methods-oh-my/

通常,它们将返回相同的结果。但是,在某些情况下,当MyName是属性时,您会遇到明显的差异,因为MyName getter在第一个示例中将执行两次,而在第二个示例中仅执行一次。

例如,两次执行MyName可能会导致性能差异:

string MyName
{
    get
    {
        Thread.Sleep(10000);
        return "HELLO";
    }
}

否则,如果MyName是有状态的,则两次执行MyName可能会得到不同的结果:
private bool _MyNameHasBeenRead = false;

string MyName
{
    get
    {
        if(_MyNameHasBeenRead)
                throw new Exception("Can't read MyName twice");
        _MyNameHasBeenRead = true;
        Thread.Sleep(10000);
        return "HELLO";
    }
}

或者,如果可以在其他线程上更改MyName,则两次执行MyName可能会得到不同的结果:
void ChangeMyNameAsync()
{
    //MyName set to null in another thread which makes it
    //possible for the first example to return null
    Task.Run(() => this.MyName = null);
}

string MyName { get; set; }

这是实际代码的编译方式。首先用三元表达式表示:
IL_0007:  ldloc.0     // s
IL_0008:  callvirt    s.get_MyName       <-- first call
IL_000D:  brfalse.s   IL_0017
IL_000F:  ldloc.0     // s
IL_0010:  callvirt    s.get_MyName       <-- second call
IL_0015:  br.s        IL_001C
IL_0017:  ldsfld      System.String.Empty
IL_001C:  call        set_MyName

这是null运算符的组成部分:
IL_0007:  ldloc.0     // s
IL_0008:  callvirt    s.get_MyName       <-- only call
IL_000D:  dup
IL_000E:  brtrue.s    IL_0016
IL_0010:  pop
IL_0011:  ldsfld      System.String.Empty
IL_0016:  call        s.set_MyName

如您所见,三元运算符的编译代码将进行两次调用以获取属性值,而null-coalescing运算符将仅执行1。

关于c# - '? … :'和 '??'这两行是否相同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21052437/

10-11 14:57