C# IF语句中运算符的顺序

C# IF语句中运算符的顺序,c#,if-statement,nullpointerexception,logical-operators,C#,If Statement,Nullpointerexception,Logical Operators,我经常在必要时这样做,以防止出现空指针异常: 在#1中,我总是假设猫!=null必须是第一个,因为操作顺序是从左到右计算的 但是,与示例#1不同,现在我想在对象为null或计数为零时执行一些操作,因此我使用的是逻辑or而不是AND: // Example #2 if (table == null || table.Rows == null || table.Rows.Count <= 0) { // Do something } 秩序很重要。这一切都与短路有关。对于ands,它遇到的

我经常在必要时这样做,以防止出现空指针异常:

在#1中,我总是假设
猫!=null
必须是第一个,因为操作顺序是从左到右计算的

但是,与示例#1不同,现在我想在对象为
null
计数为零时执行一些操作,因此我使用的是逻辑or而不是AND:

// Example #2
if (table == null || table.Rows == null || table.Rows.Count <= 0)
{
  // Do something
}

秩序很重要。这一切都与短路有关。对于ands,它遇到的第一个false将停止计算,对于ORs,它一遇到true就停止计算

它将在第一次求值后短路,这就是为什么您不会得到空指针异常

当您考虑它时,请考虑为每个对象插入null

if (null== null || null.Rows == null || null.null.Count <= 0)
{
  // Do something
}

if(null==null | | null.Rows==null | | null.null.Count在您提供的示例中:

if (table == null || table.Rows == null || table.Rows.Count <= 0)
{
  // Do something
}
要使AND子句为true,所有元素都必须为true。但是,
A()
返回false,并且运行时(或者这里的编译器,在优化步骤中,但我们不必担心…)根本不会计算
B()

OR(
|
)表达式也是如此。如果子句中的任何元素为true,从左到右求值,则不会执行子句的其余部分。

顺序无关紧要

澄清:

在IF语句中放置语句的顺序不会影响IF语句是否进入…以及结果

正如另一张海报所指出的,这将影响评估哪些项目,但这不会影响AFAIK的底线

编辑@JonHanna


我想我是从OP声明他在需要时检查NPE的Previor的角度来看的(参见他的文章的第一行)。因此,如果他的代码没有产生运行时错误,那么顺序就没有任何意义。我无法想象为什么有人在编写if语句时会想到“如果这个if语句导致NPE”然后它将不会被计算…

第一个结构与第二个结构不同。第一个结构用于在引用为null或计数为零时不执行任何操作。第二个结构将在它为null或计数为零时执行某项操作…使第二个结构与第一个结构相同你需要写:

 if (table == null || table.Rows == null || table.Rows.Count <= 0 || ) 
 {}
 else
 { 
  // Do something 
 } 

if(table==null | | | table.Rows==null | | | table.Rows.Count是的,短路在这两种情况下都会发生,唯一的区别是当LHS为false时&&stops(因为整个表达式必须为false),而当LHS为true时| |停止(因为整个表达式必须为true)


您问题中的前两个示例是正确的,如果table或table.Rows为null,则第三个示例将引发异常。

您应该注意,并非所有C#逻辑运算符都表现出短循环行为(如上所述)

您使用的是条件AND运算符(&&),这会造成短路。但是AND(&)运算符与条件AND运算符完全相同,并且没有短路

OR和条件OR运算符也是如此

例如:

//如果cats为null,则无论顺序如何,都将抛出

如果(cats!=null&cats.Count>0){}

//由于短路,这不会发生

如果(cats!=null&&cats.Count>0){}


我想你误解了我的目标。在第二次“施工”中当它为null或者计数为零时,我想做一些事情。如果是这样的话,那么第一个例子没有这样做,它是在引用不为null的时候做一些事情。或者这些例子不应该代表同一个任务吗?如果是这样的话,那么唯一的错误就是你需要颠倒顺序,因为顺序没有改变tter,正如其他人所建议的那样……非常感谢你的帮助Charles。很抱歉,我的问题对你来说不清楚;我已经对它进行了修改,以更好地说明我的意思。其他人已经解决了我想要的问题。再次感谢。空指针异常会影响底线。颠倒任务中第一个示例中的顺序旁注:VB不会让这样的运算符短路,因为你使用的是
。如果你使用
,也会短路。还有
+1:如果你编辑并只给我答案的最后6行(包括回车)我会把你作为答案。@John:谢谢,但我不想这样做;我也在为未来的读者写作。标记对你帮助最大的答案。@Jonathan Allen:omg+100!我一直想知道该死的
是干什么的!我鄙视VB:(但从现在起,我将在它中使用
而不是
。@Jonathan,这与C#没什么不同,如果你使用
,它不会短路(其他C风格的语言也是如此,但C#中使用了按位And,使用了布尔和更清晰,并且对布尔有更严格的规则).这是错误的,恰恰相反。对于ANDs,它命中的第一个错误将停止评估,因为整体陈述不可能为真;对于ORs,它可以在任何部分为真时停止评估。是的,这有点拼写错误…现在修复了。我想他也这样做了。我添加这一点是因为我认为可以更清楚地说明,但就我个人而言,我会给Michael打上钩
if (null== null || null.Rows == null || null.null.Count <= 0)
{
  // Do something
}
if( true || null.Rows == null || null.null.Count <=0)
if (null.null.Count <= 0 || null.Rows == null || null== null)
{
  // CRASH... Do something
}
if (table == null || table.Rows == null || table.Rows.Count <= 0)
{
  // Do something
}
bool A()
{
    return false;
}

bool B()
{
    return true;
}

//...

if (A() && B())
{
    // do something
}
 if (table == null || table.Rows == null || table.Rows.Count <= 0 || ) 
 {}
 else
 { 
  // Do something 
 }