【问题标题】:String concatenation with null-coalescing operator使用空合并运算符的字符串连接
【发布时间】:2013-06-16 00:15:41
【问题描述】:

我试图构建一个如下所示的字符串,但我注意到它在使用 ?? 后被切断了。运算符,无论前一个值是否为空。

"Some Text" + System.Environment.NewLine +
varOne.ToString() ?? string.Empty + System.Environment.NewLine +
varTwo.ToString()...

除非我删除 ??操作员。环顾四周后,我发现这不是首选的方法,我可能应该使用 stringbuilder 代替,但我只是好奇为什么会发生这种情况?

【问题讨论】:

  • 如果一个变量是null,在它上面调用ToString会抛出。
  • 框架中没有从ToString 返回null 的类,我怀疑这样做是个好主意。所以ToString 之后的空合并运算符没有意义。也许是这样:varOne == null ? string.Empty + System.Environment.NewLine : varOne.ToString()
  • 也许一些额外的括号可能会有所帮助。 ?? 的优先级低于 +。看看这个:msdn.microsoft.com/en-us/library/6a71f45d.aspx
  • @TimSchmelter 很好的解释,谢谢。

标签: c# string-concatenation


【解决方案1】:

看看?? Operator (C# Reference)

??运算符称为空合并运算符,用于 为可空值类型或引用类型定义默认值。它 如果操作数不为空,则返回左侧操作数;否则它 返回右操作数。

这意味着,只有在 ?? 之前的内容为空时,才会分配 ?? 之后的内容。

所以

        string sNull = null;
        string s = sNull ?? "TADA";

s 将是 TADA

        string sNull = null;
        string s = sNull ?? "TADA";
        string sNormal = s ?? "NOT TADA";

sNormal 也可以是 TADA

【讨论】:

    【解决方案2】:

    试试:

    "Some Text" + System.Environment.NewLine +
    (varOne == null ? string.Empty : varOne.ToString()) + System.Environment.NewLine +
    varTwo.ToString()...
    

    【讨论】:

    • @X.L.Ant 很好的解决方案,谢谢。我没有标记为答案的唯一原因是我想了解它为什么不起作用,而不仅仅是修复它的代码:)
    【解决方案3】:

    varOne.ToString() 永远不是null。假设我们有a ?? b + c + d ?? n,如果a != null 整个事情演变为a 而不是a + (d ?? n)(因为运算符优先级)

    【讨论】:

      【解决方案4】:

      ??操作符的意思是“如果这个操作符之前的东西不为null,则使用它,否则使用这个操作符之后的东西”。

      您可能会感到困惑的是什么构成了“此运算符之前的东西”。在你的情况下,这就是全部:

      "Some Text" + System.Environment.NewLine + varOne.ToString()
      

      这永远不会为空。即使 varOne.ToString() 返回 null(这将是 varOne 类中的一个错误,因为 ToString() 永远不应返回 null),将字符串与 null 连接的结果是原始字符串。绝对没有上述情况会导致 null。

      现在,varOne 可能为空,在这种情况下,您会遇到异常。这可能是你认为你要防范的,但事实并非如此。如果这真的是你想要的,你需要这样的东西:

      "Some Text" + System.Environment.NewLine +
      (varOne != null ? varOne.ToString() : string.Empty) + System.Environment.NewLine +
      varTwo.ToString()...
      

      这会检查 varOne 是否为空,如果不是则使用 varOne.ToString,如果是则回退到 string.Empty。

      请注意,我已经避免了这种编码风格与使用 StringBuilder 的整个问题,因为这实际上不是问题的一部分。

      【讨论】:

        【解决方案5】:

        现在答案已经改变。你可以:

        "Some Text" + System.Environment.NewLine +
        // no need to coalesce because concatenating nulls are ignored
        varOne?.ToString() 
        System.Environment.NewLine + varTwo.ToString()
        

        甚至

        $"Some Text{System.Environment.NewLine}{varOne}{System.Environment.NewLine}{varTwo}"
        // If you're not writing to a system-dependent file, \r\n will also work fine:
        $"Some Text\r\n{varOne}\r\n{varTwo}"
        

        【讨论】:

          猜你喜欢
          • 2012-05-07
          • 2010-09-29
          • 2011-06-19
          • 1970-01-01
          • 2015-04-04
          • 2012-11-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多