.NET 中依赖 && 短路安全吗?

问题描述 投票:0回答:10

假设 myObj 为空。 写这个安全吗?

if(myObj != null && myObj.SomeString != null)

我知道有些语言不会执行第二个表达式,因为 && 在执行第二部分之前计算结果为 false。

c# .net operators logical-operators short-circuiting
10个回答
104
投票

是的。在 C# 中,

&&
||
是短路的,因此仅当左侧尚未确定结果时才评估右侧。另一方面,运算符
&
|
不会短路,并且始终评估两侧。

规格说明:

&&
||
运算符称为条件逻辑运算符。它们也被称为“短路”逻辑运算符。
...
操作
x && y
对应于操作
x & y
,不同之处在于,仅当
y
x
 时才计算 
true
...
操作
x && y
被评估为
(bool)x ? (bool)y : false
。换句话说,首先评估
x
并将其转换为类型
bool
。然后,如果
x
true
,则计算
y
并将其转换为类型
bool
,这将成为运算结果。否则,运算结果为
false

(C# 语言规范版本 4.0 - 7.12 条件逻辑运算符)

&&
||
的一个有趣的属性是,即使它们不对布尔值进行操作,但它们也是短路的,而是在用户重载运算符
&
|
以及
true
和 的情况下进行类型操作。
false
运算符。

操作

x && y
被评估为
T.false((T)x) ? (T)x : T.&((T)x, y)
,其中
T.false((T)x)
是对
operator false
中声明的
T
的调用,而
T.&((T)x
, y) 是对所选
operator &
的调用。此外,值 (T)x 只能评估一次。

换句话说,首先评估

x
并将其转换为类型
T
,然后在结果上调用
operator false
以确定
x
是否肯定是
false

那么,如果
x
肯定是
false
,则运算的结果就是之前为
x
计算的值转换为类型
T

否则,将计算
y
,并对先前为
&
计算的值(转换为类型
x
)以及为
T
计算的值调用所选运算符
y
,以产生运算结果。

(C# 语言规范版本 4.0 - 7.12.2 用户定义的条件逻辑运算符)


17
投票

是的,C# 使用逻辑短路。

请注意,虽然 C#(和其他一些 .NET 语言)的行为方式如此,但它是语言的属性,而不是 CLR。


7
投票

我知道我迟到了,但在 C# 6.0 中你也可以这样做:

if(myObj?.SomeString != null)

这和上面是一样的。

另请参阅: 问号和点运算符是什么意思?在 C# 6.0 中意味着什么?


4
投票

您的代码是安全的 - && 和 ||均短路。 您可以使用非短路运算符 & 或 |,它们对两端求值,但我在很多生产代码中确实没有看到这一点。


3
投票

当然,它在 C# 上是安全的,如果第一个操作数为 false,则永远不会计算第二个操作数。


1
投票

绝对安全。 C# 就是其中一种语言。


1
投票

在 C# 中,

&&
||
是短路的,这意味着如果确定了答案,则会评估第一个条件,而忽略其余条件。

在 VB.NET 中,

AndAlso
OrElse
也是短路的。

在 JavaScript 中,

&&
||
也是短路的。

我提到 VB.NET 是为了表明 .net 的丑陋红发继子有时也有很酷的东西。

我提到 javaScript,因为如果你正在进行 Web 开发,那么你可能也会使用 javaScript。


0
投票

是的,C# 和大多数语言从左到右计算 if 语句。

顺便说一句,VB6 将计算整个事情,如果它为空,则抛出异常...


0
投票

一个例子是

if(strString != null && strString.Length > 0)

如果双方都执行的话,这行代码会导致空异常。

有趣的旁注。上面的例子比 IsNullorEmpty 方法快很多。


0
投票

虽然 C#

&&
短路是规范的一部分,但类似的 C# 运算符
and
和其他模式匹配运算符不指定计算顺序,并且编译器可以按照其想要的任何顺序自由执行它们。请参阅本页

上的注释
© www.soinside.com 2019 - 2024. All rights reserved.