VB - AndAndAlso - 有任何理由使用 And 运算符吗?

Posted

技术标签:

【中文标题】VB - AndAndAlso - 有任何理由使用 And 运算符吗?【英文标题】:VB - And AndAlso - Any reason to use the And Operator? 【发布时间】:2015-11-02 11:51:54 【问题描述】:

在评估表达式时,AndAndAlso 更受青睐的情况是什么?我假设较早的关键字只是为了向后兼容而存在,但仍然会遇到使用 And 的示例。

谢谢!

-- 问题已按要求进行了编辑,使其(更多?)独一无二。

我读到了这个问题What is the difference between And and AndAlso in VB.NET?

我了解 And 和 AndAlso 的概念差异,这不是我所问的,因为可以通过阅读来辨别。有了这个,我看不出这是一个重复的问题,Jon Hanna 已经给出了很好的答案。

再次感谢。

【问题讨论】:

What is the difference between And and AndAlso in VB.net?的可能重复 如果你要测试多个函数的布尔结果呢?如果 PostToAccounts() 和 RollOverTax() 和 PayEmployee() ? 在链接的问题中,this is the first answer 解决了您可能想要使用And 而不是AndAlso 的问题。 And 是在 VB 中执行按位运算的唯一方法(如副本中所述) 【参考方案1】:

您可以使用 And 而不是 AndAlso 的三个原因(虽然 VB.Net 运算符并不总是与 C# 运算符直接比较,但这确实适用于 C# 中的 &&&)。

第一种情况是您不比较布尔值,而是进行逐位比较。

13 And 92     ' 12
13 AndAlso 92 ' True

第二个是当您想要确保计算两个表达式时,因为有副作用。但是,在这种情况下,我建议您先计算它们,然后再执行AndAndAlso,以使代码更清晰。

第三是避免分支。考虑一下:

If x AndAlso y Then
' Do something
End If

工作原理与:

If x Then
  If y Then
  ' Do Something
  End If
End If

现在,按照现代计算机的工作方式,处理器将在知道这些指令是否真的是下一条指令之前已经读取了一些下一条指令,因为它还没有确定它是否会遵循If 分支或不。有一些聪明的东西猜测是否会采用分支,但聪明的东西仍然只是猜测。如果它猜错了,那么它必须备份,这会减慢速度。

因此,如果计算AndAlso 的第二个参数所需的时间小于某个阈值,And 实际上可能更快,因为虽然从概念上讲,AndAndAlso 完成的工作更多在第一个参数是False(允许AndAlso 短路)的情况下,只有一个分支可以预测而不是两个,并且正确猜测哪个分支更大的几率。 (在此处搜索“分支预测”和“分支错误预测”以了解有关该一般问题的更多信息)。

【讨论】:

您关于处理器推测执行的 cmets 让我想知道 vb/c# 编译器和 .NET 抖动在这方面有多聪明 - 即它是否可以判断使用 AndAlso 时是否有副作用并转换如果不是,则将它们转换为对推测执行友好的代码...另一个要添加到越来越多的待调查事项列表中的主题... @JamesThorpe 在大多数情况下都不会,尽管可能会有例外。一个问题是,通常很难仅从代码中预测哪个分支会更常见。并且在某种程度上,分支预测器已经在做这样的工作了。几率取决于处理的实际数据以及表达式本身的相对成本,因此需要从更大的角度来合理猜测And 何时会比AndAlso 快。你可以注意可空值的提升如何倾向于使用And/& 而不是AndAlso/&& @JamesThorpe ...它将对HasValue 的检查与从GetValueOrDefault 获取结果相结合以产生提升的运算符结果。 @JamesThorpe 如果不出意外,如果您尝试应用如此高级别的知识(或者只是分析两者以查看哪个做得更好)并且编译器认为它比您更了解并且无论哪种方式,都可以将不同的方法转换为相同的代码。 @StevenKirkland 我同意这是一个接近但不完全相同的副本。人们可以很好地阅读该问题的大部分内容,但对“好吧,为什么不一直使用AndAlso?”没有很好的答案。那里有一个关于想要同时产生副作用的答案,但我个人认为,如果你需要两种副作用,最好将它们作为单独的陈述,以便更清楚地说,正如我所说。没有人提出在那里分支的问题。

以上是关于VB - AndAndAlso - 有任何理由使用 And 运算符吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何理由继续使用 IntentService 处理 GCM 消息?

是否有任何理由使用一个 DataContext 实例,而不是几个?

是否有任何理由对同一资源使用“Vary: *”和“Vary: Foo”响应?

是否有任何理由使用右值引用重载运算符?

是否有任何陷阱或充分的理由不使用 autosproc 进行存储过程调用?

你知道使用 Apache 而不是 Nginx 的任何理由吗? [关闭]