三元運算式及一行式寫法還是少用一點吧...

  • 9237
  • 0

三元運算式及一行式寫法還是少用一點吧...

 

dotBlog 的標籤: ,

昨天某隻很舊的程式,裡面有一個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)。一開始發文時的標題,我漏字了,恐怕造成誤會,在此說明,請見諒。文中加【】是修正補上文字。

--------
沒什麼特別的~
不過是一些筆記而已