在 C# 中,是否保证表达式从左到右进行评估?
例如:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
有没有不符合的语言?
在 C# 中,是否保证表达式从左到右进行评估?
例如:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
有没有不符合的语言?
您实际上指的是一种称为“短路逻辑表达式”的语言功能:
这意味着:当一个逻辑表达式的结果不能再改变时,例如当很明显该表达式无论如何都会计算为“真”或“假”时,表达式的其余部分将不会被计算。
例如,C#、Java 或 JavaScript 可以做到这一点,您可以在这些语言中依赖它(回答您的问题)。
在您的情况下,如果 MyClass 不为空:
MyClass == null
评估为假myClass.Property > 0
决定最终结果如果 MyClass 为空:
MyClass == null
评估为真有些语言不会短路逻辑表达式。经典 VB 就是一个示例,如果 MyClass 为空(在 VB 中称为“Nothing”),此处将评估“myClass.Property > 0”并产生错误。
C# 3.0 规范的第 7.11 节描述了短路:
操作 x || y 对应于操作 x | y,除了只有当 x 不为真时才评估 y。
所以,是的,你很好。
至于其他语言——我从不喜欢代表所有语言。在 VB.NET 中,您可以使用短路的 OrElse 和 AndAlso,但普通的 Or 和 And 没有。
不过要小心:
如果你有类似的东西
sprintf(buf, "%s %s", func1(&var), func2(&var));
对 var 有副作用,它没有定义(在 C 中,我不确定评估顺序是否在其他语言中定义),执行 func1() 和 func2() 的顺序(这取决于,以什么顺序(左或对)参数被放入堆栈并从那里评估。
我不确定,您真的对订单或短路评估感兴趣吗?
我不是 100% 确定,但据我所知,C# 中的评估顺序始终是相同的(我假设大多数(如果不是全部).net 语言)。短路评估的工作原理如前面的答案中所述。
但是,在 C# 中,您可以选择不使用简单的运算符(用 & 代替 &&)进行短路。通常您想要短路,但也可能是您想要执行所有评估的情况。
Ada、Visual Basic 和 Pascal 等语言中的和/或运算符不会短路。它们确实提供了额外的运算符来允许该功能,例如 Ada 中的“然后”和“否则”。
Python 有短路or
和and
运算符。
在 Java 和 Haskell 中 && 和 || 短路也是如此。
有趣的是:在 Haskell 中,语言自然而然地出现了这一点(您可以定义自己的运算符来执行此操作),而在 Java 和 C# 中,它是特定于这两个运算符的。
实际上短路是一部分,但您还需要知道语言是否保证对它们进行从左到右的评估。例如 C (ANSI, ISO, C99) 不保证从左到右的评估。在示例代码中,可以在检查 NULL 之前检查 Property 的值,或者同时执行这两项操作……大多数编译器都没有,但是没有什么能阻止它这样做并完全符合规范。它甚至告诉你不要因此编写这样的代码。