【发布时间】:2010-09-23 01:20:48
【问题描述】:
在VB.NET中,And和AndAlso有什么区别?我应该使用哪个?
【问题讨论】:
-
AndAlso 在我遇到的大多数其他语言中更像 AND。 VB 对次要项进行不必要的检查似乎是一个不幸和不寻常的遗留问题——也许仅仅是因为最初的实现不是最理想的(?)。顺便说一句,可悲的是,VB 与 Or 和 OrElse 有类似的问题;)
在VB.NET中,And和AndAlso有什么区别?我应该使用哪个?
【问题讨论】:
And 运算符计算两边,其中AndAlso 计算右边当且仅当左边为真。
一个例子:
If mystring IsNot Nothing And mystring.Contains("Foo") Then
' bla bla
End If
如果mystring = Nothing以上会抛出异常
If mystring IsNot Nothing AndAlso mystring.Contains("Foo") Then
' bla bla
End If
这个不会抛出异常。
因此,如果您来自 C# 世界,您应该像使用 && 一样使用 AndAlso。
更多信息在这里:http://www.panopticoncentral.net/2003/08/18/the-ballad-of-andalso-and-orelse/
【讨论】:
Then 是它自己的关键字。
And 运算符将在继续之前检查语句中的所有条件,而 Andalso 运算符将在知道条件为假时停止。例如:
if x = 5 And y = 7
检查 x 是否等于 5,如果 y 等于 7,如果两者都为真,则继续。
if x = 5 AndAlso y = 7
检查 x 是否等于 5。如果不是,它不检查 y 是否为 7,因为它知道条件已经为假。 (这称为短路。)
如果第一部分不正确,通常人们会使用短路方法,如果有理由明确不检查第二部分,例如如果检查它会抛出异常。例如:
If Not Object Is Nothing AndAlso Object.Load()
如果使用And 而不是AndAlso,即使是nothing,它仍然会尝试Object.Load(),这会引发异常。
【讨论】:
and/or,除非他们有理由——我认为合法的理由很少而且相差甚远。当然,大多数其他语言默认短路是有原因的:它保留了结果的意义,同时在它们没有贡献时不评估可能代价高昂的表达式。在条件下隐藏副作用应该是侧眼的。但这只是我的意见......
有趣的是,没有一个答案提到 VB.NET 中的 And 和 Or 是位运算符,而 OrElse 和 AndAlso 是严格的布尔运算符。
Dim a = 3 OR 5 ' Will set a to the value 7, 011 or 101 = 111
Dim a = 3 And 5 ' Will set a to the value 1, 011 and 101 = 001
Dim b = 3 OrElse 5 ' Will set b to the value true and not evaluate the 5
Dim b = 3 AndAlso 5 ' Will set b to the value true after evaluating the 5
Dim c = 0 AndAlso 5 ' Will set c to the value false and not evaluate the 5
注意:非零整数被视为true; Dim e = not 0 会将e 设置为-1,证明Not 也是位运算符。
|| 和 &&(OrElse 和 AndAlso 的 C# 版本)返回最后计算的表达式,分别是 3 和 5。当v 为null 或(0 和一个整数)时,您可以使用 C# 中的成语v || 5 将5 作为表达式的值,否则将v 的值。语义上的差异可能会让涉足 VB.NET 的 C# 程序员措手不及,因为这种“默认值习语”在 VB.NET 中不起作用。
所以,回答这个问题:使用Or 和And 进行位运算(整数或布尔值)。使用OrElse 和AndAlso 将操作“短路”以节省时间,或在评估之前测试评估的有效性。 If valid(evaluation) andalso evaluation then 或 if not (unsafe(evaluation) orelse (not evaluation)) then
奖励:以下内容的价值是什么?
Dim e = Not 0 And 3
【讨论】:
|| 和&& 与?? 混淆了。虽然有些语言 || 将返回非 false 值,但 C# 不是其中之一,并返回 bool(提升的可空运算符除外,您会得到 Nullable<bool> 结果)
If Bool1 And Bool2 Then
计算 Bool1 和 Bool2
If Bool1 AndAlso Bool2 Then
当且仅当 Bool1 为真时才计算 Bool2。
【讨论】:
对于那些说副作用是邪恶的人来说:在一种情况下有两个副作用是好的地方就是同时读取两个文件对象。
While File1.Seek_Next_Row() And File2.Seek_Next_Row()
Str1 = File1.GetRow()
Str2 = File2.GetRow()
End While
使用And 可确保每次检查条件时都会消耗一行。而AndAlso 可能会读取File1 的最后一行并留下File2 而不使用任何行。
当然上面的代码是行不通的,但我一直在使用这样的副作用,不会认为它是“bad”或“evil”有些代码会让你相信。它易于阅读且高效。
【讨论】:
AndAlso 很像 And,只是它在 C#、C++ 等中的工作方式类似于 &&。
不同之处在于,如果第一个子句(AndAlso 之前的那个)为真,则永远不会计算第二个子句 - 复合逻辑表达式是“短路的”。
这有时非常有用,例如在如下表达式中:
If Not IsNull(myObj) AndAlso myObj.SomeProperty = 3 Then
...
End If
如果 myObj 为 null,则在上面的表达式中使用旧的 And 会引发 NullReferenceException。
【讨论】:
Not IsNull(myObj) 是假的,那么它不应该评估第二个子句。否则,它将抛出 NullReferenceException。
一种简单的思考方式是使用更简单的英语
If Bool1 And Bool2 Then
If [both are true] Then
If Bool1 AndAlso Bool2 Then
If [first is true then evaluate the second] Then
【讨论】:
另请参阅堆栈溢出问题:Should I always use the AndAlso and OrElse operators?。
另外:如果表达式的右侧有您需要的副作用,请给那些提到使用And 的人的评论:
如果右侧有您需要的副作用,只需将其移到左侧而不是使用“与”。如果 both 双方都有副作用,你只需要“And”。如果你有那么多副作用,你可能做错了什么。一般来说,你真的应该更喜欢 AndAlso。
【讨论】:
除了上述答案之外,AndAlso 还提供了一种称为短路的调节过程。许多编程语言都像 vb.net 一样内置了此功能,并且可以通过删除不必要的评估来显着提高长条件语句的性能。
另一个类似的条件是 OrElse 条件,它只在左侧条件为假时检查右侧条件,从而在找到真条件后消除不必要的条件检查。
我建议您始终使用短路过程,并以最能从中受益的方式构建您的条件语句。例如,首先测试您最有效和最快的条件,以便您仅在绝对必须时运行长时间条件并在其他时间短路。
【讨论】:
对于我们大多数人来说,OrElse 和 AndAlso 可以解决问题,除了一些令人困惑的例外情况(不到 1% 的情况我们可能不得不使用 Or 和 And)。
尽量不要被那些炫耀布尔逻辑并让它看起来像火箭科学的人冲昏了头脑。
它非常简单直接,有时您的系统可能无法按预期工作,因为它一开始就不喜欢您的逻辑。然而,你的大脑不断告诉你,他的逻辑经过了 100% 的测试和证明,并且应该有效。在那一刻停止相信你的大脑,让他再想一想,或者(不是 OrElse 或 OrElse)你强迫自己寻找另一份不需要太多逻辑的工作。
【讨论】:
用例:
使用“And”,编译器将检查所有条件,因此如果您正在检查一个对象可能是“Nothing”,然后您正在检查它的一个属性,您将遇到运行时错误。
但是如果 AndAlso 在条件中使用第一个“false”,它将检查下一个,因此您不会有错误。
【讨论】:
使用 And 和 Or 进行逻辑位运算,例如x% = y% Or 3
AndAlso 和 OrElse 用于 If 语句:
If x > 3 AndAlso x <= 5 Then
与
相同If (x > 3) And (x <= 5) Then
我的看法……
另外值得注意的是,(我)建议您在 If 语句中将带有逻辑运算符的方程括起来,这样它们就不会被编译器误解,例如:
If x = (y And 3) AndAlso ...
【讨论】: