短路声明评估 - 这是保证吗? [C#]

时间:2010-04-22 15:27:04

标签: c# conditional-operator logical-operators short-circuiting

这里有关于C#中短路语句的快速问题。使用if语句:

if (MyObject.MyArray.Count == 0 || MyObject.MyArray[0].SomeValue == 0)
{

//....
}

是否保证评估将在“MyArray.Count”部分之后停止,前提是该部分为真?否则我将在第二部分得到一个空例外。

6 个答案:

答案 0 :(得分:34)

是的,这是有保证的。

C# Language Specification - 7.11 Conditional logical operators

  

&&||运算符称为条件逻辑运算符。 它们也被称为“短路”逻辑运算符。

因此,他们将支持逻辑短路按照定义 - 您可以依赖此行为。

现在区分条件运算符和逻辑运算符非常重要:

  • 只有条件运算符支持短路,逻辑运算符不支持。
  • C#的逻辑运算符看起来就像它们的条件对应物一样,但是少了一个字符,因此逻辑OR为|,逻辑AND为&
  • 逻辑运算符可以重载但是条件运算符不能(这有点技术性,因为条件运算符求值确实涉及重载解析,并且此重载解析可以解析为类型逻辑运算符的自定义重载,因此您可以解决此问题限制在一定程度上)。

答案 1 :(得分:12)

是的,这是有保证的。

http://msdn.microsoft.com/en-us/library/6373h346%28v=VS.80%29.aspx

  

条件OR运算符(||)执行其bool操作数的逻辑或,但仅在必要时才计算其第二个操作数。

答案 2 :(得分:5)

是的,它是有保证的,但是如果MyArray为null(或者显然是MyObject),你仍然可以得到一个空引用异常。

答案 3 :(得分:2)

只是一个小小的观察。

你这样说:

  

否则我会在第二部分得到 null异常。 (强调我的)

实际上,这不是真的。如果无法保证短路,您可以在第二部分获得IndexOutOfRangeException

如果NullReferenceException对象中的第一项实际上为空(或者任何其他仍然可能会获得MyArray em>该表达式中的对象是)。

唯一完全安全检查将是:

bool conditionHolds =
    MyObject == null ||
    MyObject.MyArray == null ||
    MyObject.MyArray.Count == 0 ||
    MyObject.MyArray[0] == null ||
    MyObject.MyArray[0].SomeValue == 0;

if (conditionHolds)
{
    //....
}

答案 4 :(得分:2)

是的,

  

对于AND操作,如果任何操作数计算为false,则总表达式计算为false,则不需要评估剩余表达式。如果OR操作,如果任何操作数计算为true,则可以跳过剩余评估

所以通过使用&&或||运算符,可以在不评估所有子表达式的情况下将整个表达式计算为true或false。

但也考虑它的side effectThis article可能有助于深入了解一些现实世界的短路评估。

答案 5 :(得分:-1)

我更喜欢使用&&运算符,因为你然后测试一个正数(我的数组包含项目),而不是负数(我的错误不包含项目):

if (MyObject.MyArray.Count > 0 && MyObject.MyArray[0].SomeValue == 0) 
{ 

//.... 
} 

这也可以保证短路。