65

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

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

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

4

9 回答 9

93

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

规范说:

和运算&&||称为条件逻辑运算符。它们也被称为“短路”逻辑运算符。
...
该操作x && y对应于该操作x & y,除了y仅在xis时评估该操作true
...
该操作x && y评估为(bool)x ? (bool)y : false。换句话说,x首先评估并转换为 type bool。然后, if xis true,y被评估并转换为 type bool,这成为操作的结果。否则,运算结果为false

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

&&and的一个有趣特性||是,即使它们不是对 bool 进行操作,而是在用户重载运算符&|trueandfalse运算符一起使用的类型时,它们也会短路。

该操作x && y被评估为T.false((T)x) ? (T)x : T.&((T)x, y),其中 T.false((T)x)是对operator falsein 声明的调用T,并且T.&((T)xy) 是对 selected 的调用operator &。此外,值 (T)x 只能评估一次。

换句话说,x首先评估并转换为类型T,然后operator false在结果上调用以确定是否x为绝对false
然后,如果x是肯定false的,则操作的结果是先前计算的x转换为类型的值T
否则,y计算,并在&先前计算的值上调用选定的运算符以x转换为类型T和计算的值y以产生操作的结果。

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

于 2011-01-27T19:02:24.537 回答
16

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

请注意,尽管 C#(和其他一些 .NET 语言)以这种方式运行,但它是该语言的属性,而不是 CLR。

于 2011-01-27T19:02:09.950 回答
6

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

if(myObj?.SomeString != null)

这与上述相同。

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

于 2016-01-21T22:55:52.710 回答
4

您的代码是安全的 - && 和 || 都是短路的。您可以使用非短路运算符 & 或 | 来评估两端,但我真的在很多生产代码中看不到这一点。

于 2011-01-27T19:05:06.010 回答
3

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

于 2011-01-27T19:02:54.433 回答
1

这是完全安全的。C# 就是其中一种语言。

于 2011-01-27T19:02:28.983 回答
0

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

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

于 2011-01-27T19:03:12.210 回答
0

一个例子是

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

如果双方都执行,此行将导致 null 异常。

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

于 2011-01-27T19:30:43.423 回答
0

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

在VB.NET中,AndAlso也是OrElse短路的。

在 javaScript 中,&&也是||短路的。

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

我提到了 javaScript,因为如果你正在做 Web 开发,那么你可能还会使用 javaScript。

于 2017-10-11T16:50:00.050 回答