为什么 IIf 的实现在 Visual Basic 和 FreeBasic 中不同?

sta*_*er6 5 vb.net vb6 vba

在 FreeBasic 中,IIf (A, B, C)相当于A ? B : C在 C/C++/Java/C#、If (A, B, C)VB.NET 和B if A else Cpython 中。但是,在 VB6、Office VBA 和 VB.NET 中,IIf (A, B, C)相当于以下 C++ 代码:

bool a = A;
auto b = B;
auto c = C;
a ? b : c;
Run Code Online (Sandbox Code Playgroud)

因此,IIf在 Visual Basic 和 FreeBasic 中的工作方式不同。例如,

Dim x As Integer, y As Integer
x = 0
y = IIf (x <> 0, 12 \ x, 0)
Run Code Online (Sandbox Code Playgroud)

在 FreeBasic 中正常工作,但在 Visual Basic 中会抛出异常。这是因为在 Visual Basic 中,此代码等效于以下 C++ 代码:

int x, y;
x = 0;
bool a = (x != 0);
auto b = 12 / x;
auto c = 0;
y = a ? b : c;
Run Code Online (Sandbox Code Playgroud)

在 VB.NET 中,使用If将执行与在 FreeBasic 中使用相同的操作IIf。例如,

Dim x As Integer, y As Integer
x = 0
y = If (x <> 0, 12 \ x, 0)
Run Code Online (Sandbox Code Playgroud)

在VB.NET中不会抛出异常。

问题是:为什么IIf (A, B, C)在 VB6/VBA 中同时计算BC,而不是根据表达式 的值选择一个表达式来计算A

use*_*401 6

IIf是一个函数。它的工作原理与任何其他函数一样。它对用于生成其参数的表达式一无所知;只有他们的价值观。您在代码中编写的要传递到的任何表达式IIf都会首先计算,就像它们用于任何其他方法调用一样。

VB.NETIf在 2008 年添加了一个运算符。因为它是一个运算符,所以它的行为已融入到语言中,短路是其中的一部分,就像它是基于?:C 的语言中三元运算符 ( ) 行为的一部分一样。


Hei*_*nzi 4

只有 FreeBASIC 开发人员可以肯定地回答这个问题,但这里有一些合理的猜测:

\n
    \n
  • VB.NET 努力向后兼容 VBA/VB6。IIfVBA/VB6 中已经存在(非短路)功能。因此,使其短路会破坏向后兼容性(考虑IIf(x, SomeMethodAWithSideEffects(), SomeMethodBWithSideEffects())。因此,他们选择创建一个新的运算符If(...)。\xc2\xb9

    \n
  • \n
  • 另一方面,FreeBASIC 从未声称/尝试与 VBA/VB6 兼容,而只是与 QuickBASIC 兼容:例如,考虑一下它们的面向对象功能,这些功能具有完全不同的语法。QuickBASIC 从来没有IIf函数,因此他们可以使用语义略有不同的关键字,而不必担心向后兼容性。

    \n
  • \n
\n

现在,明显的后续问题是:为什么 VBA/VB6 的IIf运算符不会短路?再说一遍,我只能推测,我假设他们为了一致性IIf而做了非短路。对于基本方言来说,看起来像常规函数(例如)的东西突然具有短路行为,这将是令人惊讶的。但是,这只是一个有根据的猜测。除非最初的开发人员之一意外地看到这个问题,否则我不确定我们是否会得到权威的答案。IIf(a, b, c)

\n
\n

\xc2\xb9 在 .NET Framework 的第一个 Beta 版本中,它们将And和更改Or为逻辑短路运算符,并为原始 VBA/VB6 行为引入了新的BitAnd/运算符。BitOr他们必须在 RTM 版本中恢复这一更改并引入新的AndAlso/OrElse运算符,以避免破坏向后兼容性。

\n

  • @Craig:我认为这个论点是倒退的:VBA/VB 开发人员*可以*将“IIf”实现为(短路)运算符而不是函数,但他们选择不这样做。因此,“IIf”是一个函数这一事实是他们选择使其不短路的“结果”,而不是相反。 (2认同)