【问题标题】:Boolean Or containing Ternary conditional operation doesn't get short-circuited包含三元条件运算的布尔或不会短路
【发布时间】:2012-10-30 01:43:16
【问题描述】:

一般来说,短路or 运算符|| 会忽略右侧或左侧的计算结果为真。显然,我们发现了一个例外。

查看以下内容:

if (foo == null || bar != true ? foo.Count == 0 : true)
{

}

此代码在命令foo.Count 上引发空引用异常,因为foo 为空。当然,布尔逻辑允许这样做。但是,如果 foo 为 null,您会认为 or 会短路,甚至不会计算表达式的右侧,但它仍然会发生,并且会引发异常。

这是我的代码或 C# 编译器中的错误吗?是否有处理这种情况的 C# 规范的一部分?

【问题讨论】:

  • 在使用对象时添加一些代码来设置对象(foobar)可能是值得的。
  • @m1m1k 抛出了什么异常?
  • 请避免在标题中出现“乞求错误”。很有可能不是编译器/语言/库。
  • 这确实是一种布置条件语句的混乱方式。您应该使用括号分隔来明确描述操作的顺序 - 即使您想要默认行为。
  • 我会将其重写为if(foo == null || bar || !foo.Any()))。我觉得它比您的解决方案更容易阅读,即使在添加更多括号以使其按预期运行之后也是如此。

标签: c# .net short-circuiting


【解决方案1】:

那是因为您的陈述没有按预期进行评估。

你需要一些额外的括号:

if(foo == null || (bar != true ? foo.Count == 0 : true))

现在的写法等价于(由于运算符优先级):

if((foo == null || bar != true) ? foo.Count == 0 : true)    

【讨论】:

    【解决方案2】:

    不,它可以正常工作,请参阅operator precedence|| 将在 ?: 之前评估

    所以它首先评估foo == null || bar != true,然后评估? foo.Count == 0 : true,所以它更像是:

    if ((foo == null || bar != true) ? foo.Count == 0 : true)
    {
    
    }
    

    如果你想在这里使用短路,那么它应该是:

    if (foo == null || (bar != true ? foo.Count == 0 : true))
    {
    
    }
    

    【讨论】:

      【解决方案3】:

      想象一下您要检查的条件周围的括号:

      if ((foo == null || bar != true) ? foo.Count == 0 : true)
      {
      
      }
      

      因此,如果foonull,则您正在尝试读取foo.Count,这自然会导致NullReferenceException

      【讨论】:

        【解决方案4】:

        根据Operator precedence and associativity 条件运算符?: 具有最低优先级。因此它将最后执行。像这样:

        (foo == null || bar != true) ? foo.Count == 0 : true
        

        【讨论】:

          猜你喜欢
          • 2012-11-20
          • 2023-04-10
          • 1970-01-01
          • 1970-01-01
          • 2020-04-02
          • 1970-01-01
          • 2019-04-08
          • 2011-08-04
          • 2014-05-31
          相关资源
          最近更新 更多