【问题标题】:How can I optimize these null-checking operations?如何优化这些空值检查操作?
【发布时间】:2013-07-15 16:37:47
【问题描述】:

我有一个 SQL Reader 对象,我对其进行迭代,通常情况下,您永远不知道自己会得到什么。读取器返回的任何值都需要转换为双精度值,但如果它返回 null,我需要使用默认值优雅地处理它,在这种情况下为零。我开始使用与此类似的代码...

double x;
if (reader[1] is double)
    x = (double)reader[1];
else
    x = 0;

...这似乎可以解决问题,但我并不满意。我认为设计 C# 的神秘团队会为此配备一个运算符,你知道吗,there is。所以,我最终得到了一个稍微不同的实现......

var x = reader[1] as Double? ?? 0;

我不能告诉你上面的两个例子是否是等价的,因为像所有新手一样,我使用我认为可以解决问题并将其用于重要事情的代码 - 部分笑话。我所知道的是,我还没有让任何一种实现在访问数据库并获得空结果时抛出异常,这让我相信两者都按我的预期工作,但我宁愿确定。

那么,关于我的问题。有人可以解释一下我在使用这两种方法时可能遇到的潜在功能差异吗?如果可能,有人可以提供/解释第二个示例的更好实现吗?我发现 null-coalesce 运算符非常性感,但我真的不知道我是否以最好的方式实现它。谢谢。

【问题讨论】:

  • 好吧,你也可以写:var x = (reader[1] as Double?).GetValueOrDefault();。这样做的好处是 xdouble 而不是 double?。但这也隐藏了不兼容的值。如果 reader[1] 返回 string 会怎样,因为您重新排序了返回值?而不是得到一个异常(因为垃圾输入),你只是得到0 并且永远不知道垃圾输入。相反,执行正常转换:var x = ((double?)reader[1]).GetValueOrDefault()。如果它是可铸造的,它将起作用并为您提供价值或0。如果没有,它会抛出一个异常,你可以修复索引值。
  • 另外,如果你的默认值不是0,你可以使用GetValueOrDefault(defaultValue)重载。

标签: c# null-coalescing-operator


【解决方案1】:

如果您已经知道在您的情况下看起来的列位置(序数),那么最好使用正确的数据类型检索器并像这样事先检查 null

double x = reader.IsDBNull(1) ? 0 : reader.GetDouble(1);

【讨论】:

  • 我喜欢这个解决方案,它确实清楚地说明了您想要实现的目标。
  • @Jason 如何根据列名修改此答案以符合条件?即,如果我将上面的示例更改为使用 reader["Some Column"] 而不是 [1]。
  • @tjm6f4 不幸的是,没有采用列名的Get<Type>。最好的选择是先得到序数,比如int col1 = reader.GetOrdinal("Some Column");,然后你可以做double x = reader.IsDBNull(col1 ) ? 0 : reader.GetDouble(col1 );,否则你会卡住演员然后检查技术
  • @tjm6f4 应该可以很好地完成这项工作,但是如果您在循环中执行此操作,那么如果您首先获取序数,然后使用带有相应 @ 的列号循环,您将获得更好的性能987654326@方法
  • @tjm6f4 您最大的打击将是对列的查找,请参阅此链接中的备注msdn.microsoft.com/en-us/library/f01t4cfy.aspx,同时存储列序号并重新使用这将减少查找
【解决方案2】:

您的两个示例在功能上是等效的:null 将解析为 0double 将解析为其值。对于大多数实际目的,它们都可以立即运行。 (如果你真的需要知道,后者应该运行得稍微快一些)我更喜欢后者(使用空合并)以提高可读性。

但是,请注意,如果您可能遇到其他值,例如 intstring,您可能需要考虑使用 Convert.ToDouble,它将尝试转换您提供的任何值。它还将null 默认为0

【讨论】:

    【解决方案3】:

    as 关键字有额外的成本,因为它已经将对象转换为所需的类型。

    使用var x = !reader.IsDBNull(1) ? r.GetDouble(1) : 0;

    【讨论】:

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