操作员表现得很奇怪

时间:2014-03-12 12:18:51

标签: c# and-operator

我有两个变量spn和fmi。

(3064,11),(3064,14),(3064,16),(123,11)

spn得到第一个值(3064,3064,3064,123)和fmi得到(11,14,16,11)

这是代码:

    if ((Spn != 3064) && (Fmi != 11) || (Fmi != 16))
    {
        Console.WriteLine("Spn:{0}  Fmi:{1}   Added", Spn, Fmi);
    }
    else
    {
        Console.WriteLine("Spn:{0}  Fmi:{1}   skipped", Spn, Fmi);
    }

所以我希望输出显示:

(3064,14) added
(123,11) added
(3064,16) skipped
(3064,11) skipped

上面的代码是错误的,这个是正确的:

 if ((Spn != 3064) || (Fmi != 11) && (Fmi != 16))

我真的不明白。它与我之前写的完全相反,并且预计是正确的!任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

这是因为C#中的operator precedence

&&的优先级高于||,并首先进行评估。

在正确的版本中,它首先评估(Fmi != 11) && (Fmi != 16),然后评估该结果(Spn != 3064)。只有(3064,14)和(123,11)匹配。

在您的错误版本中,首先评估(Spn != 3064) && (Fmi != 11),并将结果应用于OR (Fmi != 16)。这是(3064,14),(3064,16)和(123,11)的匹配。


您希望选择发生的规则对我来说并不是很清楚,所以请自行决定,应用给出的答案。

如果要强制执行某些优先顺序,可以将一些组放入括号( ),例如

(A || B) && C

OR将在AND之前进行评估。

答案 1 :(得分:3)

根据您的示例输出,如果出现以下情况,您可能会想要将项目添加到列表中:

  • Spn不是3064或IF
  • Fmi不是11或16

将这两部分翻译成代码,我们得到:

Spn不是3064

Spn != 3064


   Fmi不是11或16

或表达另一种方式,

Fmi不是11而Fmi不是16

 Fmi != 11 && Fmi != 16


现在使用上面的项目符号列表中的OR将这两个放在一起,你得到:

Spn != 3064 || (Fmi != 11 && Fmi != 16)


我们可以选择删除括号,因为&&的优先级高于||

Spn != 3064 || Fmi != 11 && Fmi != 16

这正是你自己发现的表达方式。


根据您想要跳过的内容而不是添加内容,可能更容易。换句话说,

如果符合以下情况,请跳过一对:

  • Spn是3064 AND
  • Fmi是11或16

所以

Spn == 3064 && (Fmi = 11 || Fmi == 16)

(这次是必要的括号)

if (Spn == 3064 && (Fmi = 11 || Fmi == 16))
{
    Console.WriteLine("Spn:{0}  Fmi:{1}   skipped", Spn, Fmi);
}
else
{
    Console.WriteLine("Spn:{0}  Fmi:{1}   Added", Spn, Fmi);
}