三元運算式及一行式寫法還是少用一點吧...
昨天某隻很舊的程式,裡面有一個Function是要檢查傳入某字元是否存在於事先設定的陣列中。熟悉陣列語法的人,第一個想到的應該就是:System.Array.IndexOf(array, value),但是當初寫程式的人員應該不知道現有函式,於是自己寫了以下的Function:
Public Function CheckStrInStrAry(ByVal str As String, ByVal strAry As String()) As Boolean
Dim bRet As Boolean = False
For Each s As String In strAry
If s = str Then bRet = True
Exit For
Next
Return bRet
End Function
然後呼叫端如下:
Dim strAry as String() = New String(){"A", "B"}
Console.WriteLine(strAry.Length)
Console.WriteLine(CheckStrInStrAry("A", strAry))
Console.WriteLine(CheckStrInStrAry("B", strAry))
結果發現,檢查 “B” 時,永遠都會回傳 False。
各位看倌,發現錯誤在那了嗎?
看答案之前,先看一下,正確使用System.Array的方式:
Dim strAry as String() = New String(){"A", "B"}
Console.WriteLine(Array.IndexOf(strAry, "A"))
Console.WriteLine(Array.IndexOf(strAry, "B"))
Console.WriteLine(Array.IndexOf(strAry, "C"))
只要回傳是 -1,就是 False (不存在於陣列中),反之則為 True。
好了,回到剛剛那個 Bug,其實錯誤就在於:
If s = str Then bRet = True
Exit For
上面用了【類似】三元運算式的寫法,所以如果 s = str,就設定 bRet = True,If 判斷式結束。然後,下一行就離開迴圈!換言之,不管如果,都只會把傳入值拿來和陣列的第一個值比對,所以傳入 “B” 永遠都會得到 False 啊!但是乍看之下,還真是感覺沒錯呢……
修正如下:
If s = str Then
bRet = True
Exit For
End If
我個人,一直都很不喜歡用三元運算式【這類沒有明顯區塊化的寫法】,雖然它很簡潔,但是很容易造成誤會。還有那種C語言時代來的強者,喜歡三元運算中再包三元運算,天啊……語言本身無好壞,但是寫出來的程式是否易讀,是Team Work的關鍵因素啊!
2011/5/25 補充說明:這次看 Code 發現的 Bug,其實不算是三元運算式,只是省略的一行式寫法,VB.NET 的三元運算是用 IIf(Expression, TruePart, FalsePart)。一開始發文時的標題,我漏字了,恐怕造成誤會,在此說明,請見諒。文中加【】是修正補上文字。
--------
沒什麼特別的~
不過是一些筆記而已