VB.NET – IIF(,,) – 这两个“双方”进行了评估。 我应该注意什么情况?

我最近了解到IIF(A,B,C)function。 我很长一段时间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中做到这一切……都在一行。

不过,我已经读过,不pipeA评价为什么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.NETfunction,无需使用IIF()函数。

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

只执行ExecuteA()或ExecuteB()。 最后,内联IF与短路。

所以,如果您使用的是更高版本的VB.NET(截至2016年),如果可以的话,请使用它。

这是最常见的问题。

 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确实没有什么好的理由。 大多数情况下,它只是用来缩写代码,并给它可能造成的问题,这是不值得的。 另外,我认为这会让代码更难阅读。

另一件事情是它返回一个盒装值(即一个对象数据types),你必须转换回所需的types。

[ IIF ,而不是IFF ]

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

你的代码可能希望使用IIF作为守卫,以防止得到NullReferenceException ,如下所示:

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

但是这样做是行不通的,因为双方总是被评估。 这种情况在来自C / C ++ / C#/ Java背景的人员编写的代码中会发生很多 ,因为在这些语言中,三元运算符?:是进行短路评估的。

事实上, VS 2005 IIF()文档指出, IIF就像?:没有帮助:

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

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

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

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

那么,你也应该确保你在iif中没有任何function修改任何基于条件的数据。 我们使用If来做更多的事情。 只需要记住关于iif。

我被迫使用了一个iif(代码紧凑),我有一个代码块是从许多数组复制到一个电子表格,但数组中的“无”条目导致代码退出子程序(不崩溃),所以我将这个行包装在一个iif中,以检查数组单元是否包含任何内容 – 如果是,则返回“”,否则返回数组单元格(转换为string1st)。 所以如上所述,另一个不使用iif的原因。

由于缺乏我在MS Access中一直使用的NZfunction,所以我仍然很遗憾。