【问题标题】:If Condition Simplification如果条件简化
【发布时间】:2020-06-11 08:31:48
【问题描述】:

我正在重构一个代码 sn-p,其中我看到以下情况,我想知道它是否被简化了。

data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")

data.RecordId == 0 || data.SerialNum == "0000" 不也一样吗?

如果可能,怎么会?能详细点吗?

【问题讨论】:

  • if (data.RecordId != 0 || data.SerialNum == "0000") 简称。 data.RecordId != 0 或(如果 data.RecordId == 0data.SerialNum == "0000"
  • 我看到另一个处理&&的快捷方式评估的运行时差异:如果data.RecordId == 0在较长的表达式中为false,它将不会评估正确的部分将SerialNum,这可以避免……。像一个空参考。
  • @DmitryBychenko 你为什么删除你的答案,先生?我想检查一下?
  • @concurrencyboy 正如 Stgefano 在我的回答的 cmets 中提到的那样,您的 Q 中有一个错字,正如您所问的:“不是 data.RecordId == 0 || data.SerialNum == “0000”和那个一样吗?”这是不正确的,它是data.RecordId != 0 如果这是一个错字,那可能是你的解决方案。

标签: c# algorithm if-statement logic conditional-statements


【解决方案1】:

是的,有可能,假设您有错字(!= 而不是 ==)...

让 Wolfram Alpha 解释一下:

https://www.wolframalpha.com/input/?i=simplify%3A+R+%21%3D+0+%7C%7C+%28R+%3D%3D+0+%26%26+S%3D%3D+0000%29

R!=0 ∨ (R = 0 ∧ S = 0)

简写为:

R!=0 ∨ S = 0

一步一步的解释:

https://en.wikipedia.org/wiki/Boolean_algebra#Laws ∨ 在 ∧ 上的分布 说:

x v (y ∧ z) = (x ∨ y) ∧ (x ∨ z)

在你的情况下:

R! ∨ (R ∧ S) = (R! ∨ R) ∧ (R! ∨ S)

其中(R! ∨ R) 始终为真,您可以将其作为 and 逻辑中的第一个操作数省略:

R! ∨ (R ∧ S) = true ∧ (R! ∨ S)

R! ∨ (R ∧ S) =  (R! ∨ S)

但我看到另一种运行时差异涉及&& 的快捷评估:

如果data.RecordId == 0在较长的表达式中为false,它不会用data.SerialNum评估正确的部分,这样可以避免得到一个null ref。

【讨论】:

  • @FalcoAlexander 实际上他写了R== 0 而不是R!= 0 除非是错字(我认为是这样)答案是:不,这不一样,或者我错过了一些东西?
【解决方案2】:

你可以说:

data.RecordId != 0 || data.SerialNum == "0000"

data.RecordId == 0 检查是不必要的,我们已经确定data.RecordId != 0 不成立,因此data.RecordId == 0 是真的。请记住,布尔条件是从左到右计算的,并且它们是短路的:在 || 的情况下,如果第一个条件为真,则计算停止。

另一种看待它的方法是使用布尔逻辑,象征性地,您的表达式可以表示和简化如下:

1. ¬p ∨ (p ∧ q)
2. (¬p ∨ p) ∧ (¬p ∨ q)
3. true ∧ (¬p ∨ q)
4. ¬p ∨ q
  • p 代表条件data.RecordId == 0
  • q 表示条件data.SerialNum == "0000"
  • 在第 1 行中,我们应用了分配属性
  • 在第 2 行中,我们应用了声明 ¬p ∨ p 始终为 true 的标识
  • 在第 3 行中,我们应用了表明 true ∧ pp 的标识
  • 这就是我们如何简化第 4 行

【讨论】:

  • 你觉得它的计算如何?你介意解释一下我真正想知道的吗
  • @concurrencyboy 我现在做得更好了,用布尔逻辑解释了简化;)
【解决方案3】:

嗯,对于

data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")
  • 如果data.RecordId != 0 我们返回true
  • 如果data.RecordId != 0 失败,则only 选项为data.RecordId == 0,因此检查它是否冗余

所以我们可以删除 data.RecordId == 0:

data.RecordId != 0 || (data.SerialNum == "0000")

或者

data.RecordId != 0 || data.SerialNum == "0000"

【讨论】:

    【解决方案4】:

    是的,可能是

    data.RecordId != 0 || data.SerialNum == "0000"
    

    但是,根据您的条件 1,仅当 data.RecordId == 0 为真时才应验证 data.SerialNum == "0000"。如果data.RecordId 不是 0 怎么办。

    所以,这个对于上述情况是正确的

    data.RecordId != 0 || (data.RecordId == 0 && data.SerialNum == "0000")
    

    【讨论】:

      【解决方案5】:
      if(data.RecordId != 0)
      

      然后

      (data.RecordId == 0)
      

      会是真的。所以就不用提了

      data.RecordId != 0 || data.SerialNum == "0000"
      

      够了。

      【讨论】:

        【解决方案6】:

        嗯,简单的解释是这样的:

        当我们得到 data.RecordId != 0 || (data.RecordId==0 ...) 第一部分 (data.RecordId != 0) 表示除 0 之外的任何内容,表示 true。如果不是,那么我们将进入第二部分 (data.RecordId==0),当我们在这里时,data.RecordId 的值肯定是 0,并且意味着 始终为真。 (因为我们在条件的第一部分检查了除 0 之外的所有内容)。
        那么第二个条件唯一有价值的部分是 data.SerialNum == "0000 我们会有

        data.RecordId != 0 || data.SerialNum == "0000"
        

        【讨论】:

          【解决方案7】:

          不,它不一定与 ==0 正在检查 int 值和“0000”正在检查字符串值一样

          【讨论】:

            猜你喜欢
            • 2020-02-12
            • 2022-12-08
            • 2020-08-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-07-17
            • 2021-05-03
            • 2012-06-03
            相关资源
            最近更新 更多