【问题标题】:What is the difference between And and AndAlso in VB.NET?VB.NET 中的 And 和 AndAlso 有什么区别?
【发布时间】:2010-09-23 01:20:48
【问题描述】:

在VB.NET中,AndAndAlso有什么区别?我应该使用哪个?

【问题讨论】:

  • AndAlso 在我遇到的大多数其他语言中更像 AND。 VB 对次要项进行不必要的检查似乎是一个不幸和不寻常的遗留问题——也许仅仅是因为最初的实现不是最理想的(?)。顺便说一句,可悲的是,VB 与 Or 和 OrElse 有类似的问题;)

标签: vb.net short-circuiting


【解决方案1】:

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/

【讨论】:

  • “更多信息”链接已损坏。这是新网址:panopticoncentral.net/2003/08/18/…
  • 有人知道他们为什么不选择“AndThen”吗?我认为这会更直观。
  • 我一直认为这是违反直觉的。 AndAlso 意味着它将同时检查两者,这应该是相反的!因此,为什么我必须来 SO 来检查这样的事情(是的,我是一个 c# 人)。您也永远不必问诸如“And 和 AndAlso 之间的区别”之类的问题。太多了!我的英语老师会杀了我
  • 每当我使用 OrElse 时,我总是会想到南方公园“否则呢?” “正是”
  • @tmighty 猜测它会引起更多混乱,因为Then 是它自己的关键字。
【解决方案2】:

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(),这会引发异常。

【讨论】:

  • 如果右侧有您需要的副作用,只需将其移到左侧而不是使用“与”。如果 both 双方都有副作用,那么你只需要“And”。如果你有这么多副作用,你可能做错了什么。
  • 首先,Andalso 主要不是用于“运行时节省”,这很荒谬。其次,让第二个参数执行一些有用的“副作用”是丑陋的坏习惯。
  • 你不能争辩说它没有“在运行时保存”。而且我发现实际上有副作用的情况,并不是丑陋的坏习惯。
  • “如果有理由明确不检查第二部分,人们通常会使用短路方法” 呃,不是吗?我希望人们使用短路,除非他们有理由不这样做!没有人应该使用旧的and/or,除非他们有理由——我认为合法的理由很少而且相差甚远。当然,大多数其他语言默认短路是有原因的:它保留了结果的意义,同时在它们没有贡献时不评估可能代价高昂的表达式。在条件下隐藏副作用应该是侧眼的。但这只是我的意见......
【解决方案3】:

有趣的是,没有一个答案提到 VB.NET 中的 AndOr 是位运算符,而 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

注意:非零整数被视为trueDim e = not 0 会将e 设置为-1,证明Not 也是位运算符。

||&&OrElseAndAlso 的 C# 版本)返回最后计算的表达式,分别是 35。当vnull 或(0 和一个整数)时,您可以使用 C# 中的成语v || 55 作为表达式的值,否则将v 的值。语义上的差异可能会让涉足 VB.NET 的 C# 程序员措手不及,因为这种“默认值习语”在 VB.NET 中不起作用。

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

奖励:以下内容的价值是什么?

Dim e = Not 0 And 3

【讨论】:

  • 我认为您将||&&?? 混淆了。虽然有些语言 || 将返回非 false 值,但 C# 不是其中之一,并返回 bool(提升的可空运算符除外,您会得到 Nullable<bool> 结果)
  • 这就是我讨厌VB的原因
【解决方案4】:
If Bool1 And Bool2 Then

计算 Bool1 和 Bool2

If Bool1 AndAlso Bool2 Then

当且仅当 Bool1 为真时才计算 Bool2。

【讨论】:

    【解决方案5】:

    对于那些说副作用是邪恶的人来说:在一种情况下有两个副作用是好的地方就是同时读取两个文件对象。

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

    使用And 可确保每次检查条件时都会消耗一行。而AndAlso 可能会读取File1 的最后一行并留下File2 而不使用任何行。

    当然上面的代码是行不通的,但我一直在使用这样的副作用,不会认为它是“bad”或“evil”有些代码会让你相信。它易于阅读且高效。

    【讨论】:

      【解决方案6】:

      AndAlso 很像 And,只是它在 C#、C++ 等中的工作方式类似于 &&。

      不同之处在于,如果第一个子句(AndAlso 之前的那个)为真,则永远不会计算第二个子句 - 复合逻辑表达式是“短路的”。

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

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

      如果 myObj 为 null,则在上面的表达式中使用旧的 And 会引发 NullReferenceException。

      【讨论】:

      • 我想你的意思是当第一个子句为假时,第二个子句不会被评估?在上面的例子中Not IsNull(myObj) 是假的,那么它不应该评估第二个子句。否则,它将抛出 NullReferenceException。
      【解决方案7】:

      一种简单的思考方式是使用更简单的英语

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

      【讨论】:

      • 英文比代码更混乱,因为它没有规范!
      【解决方案8】:

      另请参阅堆栈溢出问题:Should I always use the AndAlso and OrElse operators?

      另外:如果表达式的右侧有您需要的副作用,请给那些提到使用And 的人的评论:

      如果右侧有您需要的副作用,只需将其移到左侧而不是使用“与”。如果 both 双方都有副作用,你只需要“And”。如果你有那么多副作用,你可能做错了什么。一般来说,你真的应该更喜欢 AndAlso。

      【讨论】:

        【解决方案9】:

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

        另一个类似的条件是 OrElse 条件,它只在左侧条件为假时检查右侧条件,从而在找到真条件后消除不必要的条件检查。

        我建议您始终使用短路过程,并以最能从中受益的方式构建您的条件语句。例如,首先测试您最有效和最快的条件,以便您仅在绝对必须时运行长时间条件并在其他时间短路。

        【讨论】:

        • 另外值得一提的是 IIF(立即如果),因为它不会短路并且可以创建与程序员的意图完全不同的条件,因为对真假组件都进行了评估。早些时候,有人说他们故意使用这种副作用行为,但是 - 我不认为这是一种有效的方法,因为立即如果没有以我可以检测到的方式执行评估的有目的的意图。
        • “除了上面的答案之外,AndAlso 还提供了一种称为短路的调节过程。” 上面的每个答案都集中在短路上。 :P 但很好的描述和建议。
        【解决方案10】:

        对于我们大多数人来说,OrElse 和 AndAlso 可以解决问题,除了一些令人困惑的例外情况(不到 1% 的情况我们可能不得不使用 Or 和 And)。

        尽量不要被那些炫耀布尔逻辑并让它看起来像火箭科学的人冲昏了头脑。

        它非常简单直接,有时您的系统可能无法按预期工作,因为它一开始就不喜欢您的逻辑。然而,你的大脑不断告诉你,他的逻辑经过了 100% 的测试和证明,并且应该有效。在那一刻停止相信你的大脑,让他再想一想,或者(不是 OrElse 或 OrElse)你强迫自己寻找另一份不需要太多逻辑的工作。

        【讨论】:

          【解决方案11】:

          用文字而不是鳕鱼来理解:

          用例:
          使用“And”,编译器将检查所有条件,因此如果您正在检查一个对象可能是“Nothing”,然后您正在检查它的一个属性,您将遇到运行时错误。 但是如果 AndAlso 在条件中使用第一个“false”,它将检查下一个,因此您不会有错误。

          【讨论】:

            【解决方案12】:

            使用 AndOr 进行逻辑位运算,例如x% = y% Or 3

            AndAlsoOrElse 用于 If 语句:

            If x > 3 AndAlso x <= 5 Then

            相同

            If (x > 3) And (x <= 5) Then

            我的看法……

            另外值得注意的是,(我)建议您在 If 语句中将带有逻辑运算符的方程括起来,这样它们就不会被编译器误解,例如:

            If x = (y And 3) AndAlso ...

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-01-14
              • 1970-01-01
              • 2017-08-25
              • 2011-04-21
              • 2021-08-11
              • 2011-07-29
              相关资源
              最近更新 更多