2012-01-30 72 views
3

我有以下的OR运算符,现在如果c为空,错误视图将被返回,并且在第二次检查(!c.ManagedBy ...)时不会引发null异常;但是这只会在编译器在(!c.Ismanaged ..)检查之前执行(c == null)检查时才会发生。或运算符的序列

Book c = elearningrepository.GetBook(id); 

if ((c == null) || (!c.IsManagedBy(User.Identity.Name))) 
{ 
    return View("Error"); 
} 

,所以我可以保证的是,编译器总是空检查首先进行的C ==或最好是上述检查分成两个单独的if语句来明确执行顺序。 BR

回答

5

||会发生短路,并将按照您所描述的完全评估。没有必要分开陈述。

MSDN

的条件或运算符(||)执行逻辑或布尔其的 操作数。如果第一个操作数的计算结果为真,则不计算第二个操作数 。如果第一个操作数的计算结果为false,则第二个运算符会确定整个OR表达式是否为 true或false。

编辑了最新的MSDN文章(2010)。

4

是的,你可以依靠的行为的||左操作数将首先评估,如果左操作数的计算结果为真,右边的操作数将不进行评估。

这是保证在C#4规范的章节7.12:

  • 操作x || y对应于操作x | y,不同之处在于y被评估仅当x是不正确的。
+0

@MagnusHoff:真;已编辑。 – 2012-01-30 16:20:44

1

我只为更加清晰起见分开吧。

+0

将它们分开可能会导致不必要的嵌套。这当然是一个选择的问题,但没有理由使它们成为单独的条件。 – Yuck 2012-01-30 16:00:14

+0

@yuck这个if语句相当简单,但在处理更复杂的语句时,我总是更喜欢“浪费”一些字符/行,以便更清楚地查看语句。 – 2012-01-30 16:02:43

+0

@Hezi:我同意Yuck。分离这种情况下,需要两次“查看”(“错误”)返回,而不仅仅是“浪费”字符/行和计算时间,而且其他开发人员在未来支持此代码时必须分别通读案例不是必需的 – nybbler 2012-01-30 16:09:28

1

编译器将始终首先评估左表达式。如果它评估为true,则会跳过正确的一个。

2

所以我可以保证编译器将总是执行与c == NULL 检查第一

是这是有保证时,操作者||将计算结果为true第一个条件后短路(评估顺序是从左到右)。

1

是的,||操作保证了第一个操作数先评估,如果第一个是假的第二个操作数只计算了。

1

是的。 ||解决左到右,这意味着左操作将首先评估,然后在右侧。它也会短路,所以当左边的操作数是true时,不用担心右边的操作数正在被评估。最后,它也有比==!较低的优先级,所以你甚至可以删除括号,它仍然是完全安全的,永远不会让你失望:)

if (c == null || !c.IsManagedBy(User.Identity.Name)) 
{ 
    return View("Error"); 
}