C# 從 7.0 開始加入了模式比對(Pattern Matching),最大的改變是將 switch 從常數比對中解放,讓 switch 可以比對運算式,到了 C# 8.0 更猛了,微軟弄了一個遞迴模式比對(Recursive Pattern Matching),大括號 "{}" 及小括號 "()" 寫到你不要不要的,但是模式比對裡面藏了一個 var
的陷阱,我就踩中了。
C# 8.0 的遞迴模式比對中有一個 Property Pattern Matching 的語法,我們直接看程式碼比較快,假設我的 Employee
集合中有 4 筆資料,透過 Filter()
方法可以回傳 Employee 的 Id 跟 Name,而且 Property Pattern Matching 預設會幫我們把 Id 跟 Name 為 Null 的資料給過濾掉。
按照我集合中的資料,過濾出來的資料筆數只會有 2 筆。
我利用 Property Pattern Matching 預設會過濾掉 Null 值的特性,想說把 Address 為 Null 的也給過濾掉,於是我加了一個條件。
預期應該只會有 1 筆資料,結果跑出來還是 2 筆。
但是如果不用 var 改用明確型別 Address
,它跑出來的結果就符合預期。
正當我百思不得其解還以為找到微軟的 Bug 之際,我搜尋到這份原廠文件,當中的規則二:
var 宣告不具有其他類型模式運算式所包含的 Null 檢查。 這表示變數可能是 null,並且在這種情況下需要 null 檢查。
真相大了個白「這不是 Bug,是 Feature。」,所以針對我剛剛使用 var 的情境,我必須額外做 Null 判斷(或改用明確型別),結果就符合預期了。
另外 C# 8.0 的 Property Pattern Matching 允許我們直接用 { }
來宣告輸出參數的型別,編譯器會幫我們做型別推斷,下面程式碼的結果等於使用明確型別,一樣會做 Null 檢查。