如果默认为null,那么在C#中使用null-coalescing运算符总是重新计算?

时间:2014-05-15 20:26:58

标签: c# refactoring simplify null-coalescing-operator

在C#中是

x = y ?? null;

总是相当于

x = y;

如果x和y都是可空类型?

我想不出为什么在第二行中需要第一行代码的原因。

3 个答案:

答案 0 :(得分:4)

是的,写一行

x = y ?? null;

看起来很愚蠢,因为如果null为空(因此基本上返回y)和y,表达式将返回y

请记住,null-coalescing运算符功能与写入相同:

x = y != null ? y : <whatever operand>

或者,当然(对于那些不熟悉三元运算符的人):

if (y != null)
   x = y;
else
   x = <whatever operand>;

在任何一种情况下,使用null作为第二个参数都没有任何实用程序。您也可以只分配变量,如帖子中所述。

答案 1 :(得分:2)

是的,它们在功能上是一样的。写

没有意义

x = y ?? null超过x = y

如果您有点好奇,x = y ?? null生成的IL代码比x = y生成的IL代码更复杂。

x = y ?? null

IL_0014:  ldloc.0     // y
IL_0015:  stloc.2     // CS$0$0000
IL_0016:  ldloca.s    02 // CS$0$0000
IL_0018:  call        System.Nullable<System.Int32>.get_HasValue
IL_001D:  brtrue.s    IL_002A
IL_001F:  ldloca.s    03 // CS$0$0001
IL_0021:  initobj     System.Nullable<System.Int32>
IL_0027:  ldloc.3     // CS$0$0001
IL_0028:  br.s        IL_0036
IL_002A:  ldloca.s    02 // CS$0$0000
IL_002C:  call        System.Nullable<System.Int32>.GetValueOrDefault
IL_0031:  newobj      System.Nullable<System.Int32>..ctor
IL_0036:  nop         
IL_0037:  stloc.1     // x

x = y

IL_0009:  ldloc.0     // y
IL_000A:  stloc.1     // x

答案 2 :(得分:1)

是的,它是等价的。即使您有DynamicObject 尝试Coalesce operation提供特定行为,也永远不会输入TryBinaryOperation。以下代码不会打印任何内容。

void Main()
{
    dynamic y = new MyDyn(); // or with this null
    dynamic z = new MyDyn();
    object x = y ?? z;
}
public class MyDyn : DynamicObject
{
    public override bool TryBinaryOperation(
        BinaryOperationBinder binder,
        Object arg,
        out Object result
    )
    {
        Console.WriteLine("Hello world!");
        if (binder.Operation == ExpressionType.Coalesce)
        {
            result = 3;
            return true;
        }
        result = null;
        return true;
    }
}