【问题标题】:C# 6.0 null-coalescing not working correctly for meC# 6.0 null-coalescing 对我来说无法正常工作
【发布时间】:2017-07-04 15:40:35
【问题描述】:

很简单的问题,下面的代码抛出了“Nullable object must have a value”异常。但我以为 ??会处理吗?

  string qty = stop.pallets_qty_total.Value.ToString() ?? "0";

【问题讨论】:

  • 不,x ?? v 大致相当于x == null ? v : x。您是指?. 运算符吗?在这种情况下,您应该使用pallets_qty_total?.ToString() ?? "0"
  • stop.pallets_qty_total 为空时,访问stop.pallets_qty_total.Value 已经抛出了这个异常——所以它甚至没有到达?? 运算符。
  • @MikhailLobanov - 它被称为null conditional operator

标签: c#


【解决方案1】:

您正在检查nullstop.pallets_qty_totalValue 属性上调用ToString() 方法后返回的结果,而stop.pallets_qty_total 有可能是null,它也是stop 本身可能是 null,这也会导致您的代码失败。

您需要使用 Null-Propogation 运算符尝试以下操作:

string qty = (stop?.pallets_qty_total?.ToString()) ?? "0";

【讨论】:

  • 你说得对,谢谢。我会在允许的时候接受。
【解决方案2】:

虽然cmets已经给出了正确答案,这里再详细解释一下:

你是对的,?? 运算符将采用左操作数,它的值不为空。否则它将采用正确的操作数。简短的版本是必不可少的:

var qty = input == null ? "0" : input;

但是,分配不会引发异常。调用ToString() 会引发异常。

如果您的输入是null,则您的语句等于以下内容:

var qty = ((object)null).ToString();

这显然会引发NullReferenceException

解决方案:

您正在寻找的是?. 运算符。上面写着“如果对象不为空,则调用函数”。这扩展为以下内容:

input != null ? input.ToString() : null
// is equal to
input?.ToString()

所以赋值的解决方案应该是两个运算符的组合:

var qty = input?.ToString() ?? "0"; 

【讨论】:

    【解决方案3】:

    您正在尝试访问Nullable<T> 的[Value][1] 属性,但它没有分配值。正如规范所说,它会抛出异常:

    如果 T 类型的值尚未分配给 Nullable 对象, 您可以将其与 null 进行比较并检索其 HasValue 属性,但是您 无法访问其 Value 属性或调用其其他成员。

    这里有两个选项 - 如果 object 为 null,请使用 null-conditional operator 来避免访问对象属性:

    string qty = stop.pallets_qty_total?.Value.ToString() ?? "0";
    

    或者你可以记住数字类型的默认值是零。如果 nullable 没有赋值,则获取默认值:

    string qty = stop.pallets_qty_total.GetValueOrDefault().ToString();
    

    那也太小了premature performance optimization

    【讨论】:

    • 知道我应该加载我在写我的时候发布的答案。
    【解决方案4】:

    就像 Ehsan Sajjad 的回答一样,假设 pallets_qty_total 是一个整数,您实际上不需要第二个 ?。您可以改为使用Nullable.GetValueOrDefault(),如下所示:

     string qty = stop?.pallets_qty_total.GetValueOrDefault().ToString();
    

    如果pallets_qty_total 有一个值,它将返回它。如果不是,它将返回default(T),对于int,它是0

    【讨论】:

      【解决方案5】:

      它只会检查Value是否为null,但如果之前的对象为null,那么它会抛出异常。

      string qty = stop?.pallets_qty_total?.Value.ToString() ?? "0";
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-14
        相关资源
        最近更新 更多