【问题标题】:Is using the null-coalescing operator in C# always redunant if defaulting to null?如果默认为 null,在 C# 中使用 null-coalescing 运算符是否总是多余的?
【发布时间】:2014-07-04 11:24:51
【问题描述】:

在 C# 中是

x = y ?? null;

总是等价于

x = y;

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

我想不出为什么需要第一行代码而不是第二行。

【问题讨论】:

  • 我正在使用 null-coalescing 运算符重构 if 语句,并注意到 smart sense 和 refactor 对此没有任何提示。我很好奇。

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


【解决方案1】:

是的,写一行

x = y ?? null;

看起来很傻,因为如果y 为空,则表达式将返回null(所以基本上返回y),否则返回y

请记住,空合并运算符在功能上与写作相同:

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

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

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

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

【讨论】:

  • @GrantWinney,我的错。感谢收看!
  • 你能不能也这样做if( x ?? y) == null
  • @DJKRAZE,该声明等同于if (x == null &amp;&amp; y == null)。这是一种非常奇怪的方式来写那个声明,所以我不推荐它。你想表达/指出什么?
  • 你是对的,我误读了,好像 OP 正在检查两者是否 == 为 Null 我意识到他在 else 检查中缺少:
  • @DJKRAZE,只是为了确保您理解正确,空合并运算符没有 : 运算符,并且 OP 没有条件语句。问题是关于将null 作为空合并运算符的第二个参数的效用,答案是“没有”。
【解决方案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

【讨论】:

    【解决方案3】:

    是的,它是等价的。即使您有一个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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-12
      • 2015-01-20
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 2012-11-21
      • 1970-01-01
      • 2015-01-31
      相关资源
      最近更新 更多