[VB] 盡量不要用 IIf 函式,改用 If

Visual Basic 的 IIf 函式會評估所有傳入的引數,這有時會造成問題,例如:

'   示範 IIf 函式的陷阱
    Dim i = 0
    Dim j = IIf(i <> 0, 10 \ i, 0)  '執行時會出錯! 

    Dim x As Integer?
    Dim y = IIf(x.HasValue, x.Value, 0)   '執行時會出錯!

第 3 行和第 6 行的寫法,在執行時都會出錯,因為 IIf 不管第一個引數的布林運算結果為 True 還是 False,後面兩個引數的數值都會被評估。

如果改用 If 函數,由於它具有短路(short circuit)的特性,只會評估其中一個引數值,因此相對保險一些。改寫之後程式碼如下:

'   改用 If 函式
    Dim i = 0
    Dim j = If(i <> 0, 10 \ i, 0)  'OK!

    Dim x As Integer?
    Dim z = If(x.HasValue, x.Value, 0)  'OK!

If 函式還提供兩個參數的版本,即省略第一個引數,但此時的第二個引數必須是參考型別或 nullable 型別。所以前面範例的第 6 行程式碼可以改寫為:

'   傳入兩個引數的 If 函式
    Dim z = If(x, 0)

註:以上程式碼是以 Visual Basic 2010 (VB 10.0)撰寫。

4 則留言:

  1. 如果是用VB.NET, 建議要改用AndAlso取代And, 用OrElse取代Or, 因為這樣才會有short-cut(short circuit) evaluation.

    回覆刪除
  2. 嗯,我也幾乎都是用 short circuit 的運算子。但不知你說的 VB.NET 是否特別指 VB.NET 2003?
    現在已不特別加上 .NET 了,如果沒有特別聲明(如 VB6),Visual Basic 一般就是指 .NET 平台上的 VB。

    回覆刪除
  3. 是否 Dim i=0
    應該將 i 明確指定成 Integer 呢?

    回覆刪除
  4. 這是 Visual Basic 9.0 的功能:型別推測。
    編譯器會知道 i 是整數喔!

    回覆刪除

技術提供:Blogger.