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

Bri*_*ter 50 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

Dim X as integer = IIF(SomeBoolean = true, ExpensiveFunction1(), ExpensiveFunction2())
Run Code Online (Sandbox Code Playgroud)

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

在某些情况下,使用旧式设计是一个相当大的偏差:

Dim X as integer
if SomeBoolean = true then
  X = ExpensiveFunction1()
else
  X = ExpensiveFunction2()
end if
Run Code Online (Sandbox Code Playgroud)

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

2016年更新

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

if(Something = true, ExecuteA(), ExecuteB())
Run Code Online (Sandbox Code Playgroud)

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

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

Joh*_*nFx 38

这是最常见的问题.

Z = iif(y=0, 0, x/y)  'Throws a divide by zero exception when y is 0
Run Code Online (Sandbox Code Playgroud)

不要使用它来避免除零错误.

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

Z = iif(FunctionA(InputOutputParam), FunctionB(InputOutputParam))
'InputOutputParam is indeterminate or at least ambiguous here.
Run Code Online (Sandbox Code Playgroud)

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

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

  • 你确定,乔尔?我正在重新检查这个,但是如果y = 5则不会看到它如何将除以零.当然假设VB.NET,对于C#我看到了你的观点,但OP问题上的标签另有说明. (4认同)

lav*_*nio 33

[ IIF,不是IFF]

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

您的代码可能希望IIF用作防守来避免获取NullReferenceException,如下所示:

IIF(something Is Nothing, "nothing", something.Value)
Run Code Online (Sandbox Code Playgroud)

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

而事实上,在VS 2005 IIF()文档指出,IIF仅仅是喜欢?:没有帮助:

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

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

  • +1 为清楚起见。2008 年的文档已更新以明确提及缺少短路评估,并建议使用“If”代替。 (2认同)

Amb*_*ber 28

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

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

  • @ hamlin11:不,你应该总是使用If()IMO.Iif()可能是为了向后兼容而保留的. (3认同)
  • If*运算符*与AndAlso和OrElse运算符JohnFx无关.它是一个独立的独立三元运算符. (2认同)
  • 因此,似乎在上面的答案中链接的If()运算符会导致IIF过时.当If()可用时,是否有人会使用IIF()?(注意:IF()不会同时评估*true*和*false*个案).我错过了什么吗? (2认同)