VB.NET - IIF(,,) - 评估两个“边”。我应该注意哪些情况?

时间:2009-08-03 01:50:28

标签: vb.net

我最近了解了IIF(A,B,C)功能。我是一个很长一段时间的VB / VB.NET Coder,他最近花了很多时间来加速SQL编码。

SQL中常见的一件事就是如下:

select (case where @var = 0 then MyTable.Val1 else MyTable.Val2 end) from MyTable

IIF(A,B,C)将允许我在VB.NET中执行此操作...所有这些都在一行上。

但是,我已经读过,无论A评估的是什么,B和C都会被评估。

我可以想到一些明显的情况,这是一件坏事,例如:

Dim X as integer = IIF(SomeBoolean = true, ExpensiveFunction1(), ExpensiveFunction2())

正如我将在我的保留曲目中包括这些,是否有更微妙的情况我可能会使用IIF遇到麻烦?

在某些情况下,使用老式的是一个非常大的偏离:

Dim X as integer
if SomeBoolean = true then
  X = ExpensiveFunction1()
else
  X = ExpensiveFunction2()
end if

我希望将来可以省去一些恼人的性能问题和/或错误。

2016年更新

在过去几年中,存在一个新的VB.NET功能,无需使用IIF()函数。

if(Something = true, ExecuteA(), ExecuteB())

仅执行ExecuteA()或ExecuteB()。最后,内联IF具有短路。

因此,如果您使用的是VB.NET的更高版本(截至2016年),请尽可能使用此版本。

5 个答案:

答案 0 :(得分:37)

这是最常见的问题。

Z = iif(y=0, 0, x/y)  'Throws a divide by zero exception when y is 0

请勿使用它来避免除以零错误。

另一个可能的逻辑错误是当iif的一侧或另一侧调用修改系统状态或具有输出参数的方法时。

Z = iif(FunctionA(InputOutputParam), FunctionB(InputOutputParam))
'InputOutputParam is indeterminate or at least ambiguous here.

根据我的经验,没有充分的理由使用IIF。它主要用于缩写代码并给出它可能导致的问题,但这不值得。另外,我认为它使代码更难阅读。

另一件事就是它返回一个盒装值(即一个Object数据类型),你必须将它转换回所需的类型。

答案 1 :(得分:33)

[IIF,而非IFF]

我们看到的最常见的情况是,一方或另一方评估为Nothing

您的代码可能希望使用IIF作为后卫,以避免获得NullReferenceException,如下所示:

IIF(something Is Nothing, "nothing", something.Value)

但这不起作用,因为双方总是被评估。在来自C / C ++ / C#/ Java背景的人编写的代码中会发生 lot ,因为在这些语言中,三元运算符?:会进行短路评估。

VS 2005 IIF() documentation表明IIF?:一样的事实无效:

  

IIf函数提供了三元条件运算符的对应物: :在Visual C ++中。

在该参考页面上没有任何地方表明双方都被评估。

答案 2 :(得分:28)

根据MSDN,VB2008中引入的“If”运算符会短路,这对于昂贵的计算案例来说是理想的:

http://msdn.microsoft.com/en-us/library/bb513985.aspx

答案 3 :(得分:1)

那么,您还应该确保在iif中没有任何根据条件修改任何数据的函数。我们使用If用于相当多的。关于iif。

是值得记住的

答案 4 :(得分:0)

我被迫使用iif(代码的紧凑性),我有一大堆代码将许多数组中的值复制到电子表格中,但数组中的“无”条目导致代码退出子程序(没有崩溃),所以我将线包裹在iif中以检查数组单元是否包含任何内容 - 如果是,则返回“”否则,传回数组单元格(转换为字符串1st)。 如上所述,另一个原因是不使用iif。

由于缺乏我在MS Access中一直使用的新西兰功能,我仍然在哀悼。