VB.NET中And和AndAlso有什么区别?


Answers:


380

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/


2
“更多信息”链接已损坏。这是新的网址:panopticoncentral.net/2003/08/18/…–
罗里·奥肯

12
有人知道为什么他们没有选择“ AndThen”吗?我认为这会更直观。
tmighty 2014年

7
我一直认为这与直觉相反。而且也暗示它将同时检查两者,这应该是相反的方式!因此,为什么我必须来SO检查这种事情(是的,我是ac#家伙)。您也永远不必问“ And与AndAlso之间的差异”之类的问题。太多了!我的英语老师会杀了我
罗宾·法兰西

3
每当我使用OrElse时,我总是会想到南方公园“否则呢?” “恰好”
罗宾·法兰西

1
@tmighty猜测这将引起更多的混乱,因为这Then是它自己的关键字。
宾基

29

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而不是AndAlsoObject.Load()即使使用,它仍会尝试nothing,这将引发异常。


14
如果右侧有副作用,只需将其移至左侧即可,而不要使用“ And”。你只有真正需要“和”如果双方互有副作用。如果发生了很多副作用,则可能是在做其他错误。
Joel Coehoorn

1
首先,Andalso并不是主要用于“节省运行时”,这很荒谬。其次,让第二个参数执行一些有用的“副作用”是不好的坏习惯。
Tor Haugen

2
您不能说它不会“节省运行时间”。而且我发现了实际上存在副作用的情况,而不是丑陋的不良做法。
Ed Marty

1
“一般来说,如果有理由明确地不检查第二部分人们会使用短路方法。”嗯,是吗?我希望人们使用短路,除非他们有理由不这样做!除非有理由,否则没有人应该使用旧的and/ or,我认为合法的理由很少,而且相差甚远。当然,大多数其他语言在默认情况下会短路是有原因的:它保留了结果的含义,同时在不做任何贡献的情况下不评估可能代价高昂的表达式。在某些情况下隐匿副作用应该是有目的的。但这只是我的意见...
underscore_d

20

有趣的是没有一个答案提到,AndOr在VB.NET是位运营商,而OrElseAndAlso严格的布尔运算符。

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也是位运算符。

||&&(的C#版本OrElseAndAlso)分别返回最后一个计算的表达式,该表达式分别是35。这使您可以使用v || 5C#中的惯用法5vis null或(0和一个整数)的值赋作表达式的值,v否则赋值。语义上的差异可以使C#程序员在VB.NET中措手不及,因为该“默认值习惯用法”在VB.NET中不起作用。

因此,要回答这个问题:将OrAnd用于位运算(整数或布尔值)。使用OrElseAndAlso“短路”操作可节省时间,或在评估之前测试评估的有效性。If valid(evaluation) andalso evaluation then要么if not (unsafe(evaluation) orelse (not evaluation)) then

奖励:以下各项的价值是什么?

Dim e = Not 0 And 3

我想你混淆||&&??。虽然有些语言||会返回非假值,但C#并不是其中一种,并且返回a bool(提升的可为空的运算符除外,在这里您会得到Nullable<bool>结果)
Ben Voigt


13

对于所有认为副作用是邪恶的人:在一个条件下具有两种副作用的良好环境将是串联读取两个文件对象。

While File1.Seek_Next_Row() And File2.Seek_Next_Row()
    Str1 = File1.GetRow()
    Str2 = File2.GetRow()
End While

使用And确保每次检查条件时消耗一行。而AndAlso可能会读取的最后一行,File1File2没有消耗的行。

当然,上面的代码是行不通的,但是我一直都在使用类似的副作用,并且不会认为它是“ 坏的 ”或“ 邪恶的 ”代码,因为有些代码会让您相信。易于阅读且高效。


5

考虑它的一种简单方法是使用更简单的英语

If Bool1 And Bool2 Then
If [both are true] Then


If Bool1 AndAlso Bool2 Then
If [first is true then evaluate the second] Then

3
英语比代码更容易混淆,因为它没有规范!
宾基

5

AndAlso非常类似于And,不同之处在于它在C#,C ++等环境中与&&类似。

区别在于,如果第一个子句(AndAlso之前的那个)为真,则第二个子句将永远不会求值-复合逻辑表达式为“短路”。

有时这非常有用,例如在诸如以下的表达式中:

If Not IsNull(myObj) AndAlso myObj.SomeProperty = 3 Then
   ...
End If

如果myObj为null,则在上面的表达式中使用旧的And将抛出NullReferenceException。


5

另请参阅堆栈溢出问题:是否应该始终使用AndAlso和OrElse运算符?

另外:对那些使用And表达式右侧是否具有副作用的人的注释:

如果右侧有副作用,只需将其移至左侧即可,而不要使用“ And”。你只有真正需要“和”如果双方互有副作用。如果发生了很多副作用,则可能是在做其他错误。通常,您确实应该更喜欢AndAlso。


3

除上述答案外,AndAlso还提供一种称为短路的调节过程。许多编程语言都像vb.net一样内置了此功能,并且可以通过消除不必要的评估来在长条件语句中显着提高性能。

另一个类似的条件是OrElse条件,该条件仅在左侧条件为假时才检查右侧条件,因此在找到真实条件后便会删除不必要的条件检查。

我建议您始终使用短路流程并以可以从中受益最大的方式来构造条件语句。例如,首先测试最有效和最快的条件,以便仅在绝对需要时运行长期条件,而在其他时间将其短路。


还值得一提的是IIF(即时If),因为它不会短路,并且可以创建条件,这与程序员的意图大不相同,因为对真假分量都进行了评估。早些时候,有人说他们有意使用这种副作用行为,但是-我不认为这是一种有效的方法,因为“即时如果”没有以我可以检测到的方式进行评估的目的。
Jinzai

“除了上述答案之外,AndAlso还提供了一种称为短路的调节过程。” 上面的每个答案都集中在短路上。:P但是很好的描述和建议。
underscore_d

1

对于我们大多数人来说,OrElse和AndAlso都会做到这一点,除了一些令人困惑的例外(在我们可能必须使用Or和And的情况下,少于1%)。

尽量不要被那些炫耀布尔逻辑并使之看起来像火箭科学的人所迷惑。

这非常简单明了,有时您的系统可能无法按预期运行,因为它一开始就不喜欢您的逻辑。但是,您的大脑一直在告诉您,他的逻辑经过100%的测试和证明,并且可以正常工作。在那一刻,不要再信任您的大脑,要求他再思考一次,或者(不是OrElse或OrElse)您强迫自己去寻找另一项不需要太多逻辑的工作。


0

用单词而不是鳕鱼来理解:

用例:
使用“和”,编译器将检查所有条件,因此,如果您检查某个对象可能为“无”,然后检查其属性之一,则将出现运行时错误。
但是在条件为第一个为“ false”的情况下,AndAlso会检查下一个,因此不会出现错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.