C# 7.0 新特性(3): 模式匹配

發表於2016-06-17

本文參考Roslyn專案Issue:#206,及Docs:#patterns

  1. C# 7.0 新特性1: 基於Tuple的“多”返回值方法

  2. C# 7.0 新特性2: 本地方法

  3. C# 7.0 新特性3: 模式匹配

模式匹配也許能算的上C#本次更新最重量級的升級,也是最受關注的特性(也許沒有之一),通過模式匹配,我們可以簡化大量的條件程式碼。

Switch語句

大家也許遇到過這樣的情景,假設你的程式碼中,有一個Nullable的值,需要對其在正整數非正整數Null三種情況下分別作不同的邏輯處理。大多數童鞋直接想到是類似於下面的邏輯:

請大家思考一下,這個邏輯是否可以用switch-case語句來做,在VB及很多非C系的語言中,答案是肯定的,比如VB.NET中可以這樣寫:

說到這裡,在具體討論模式匹配在switch-case中的應用之前,先淡淡的吐槽一下C#,本來理所應當的一個簡單的小語法,到了C#7.0才加入。

看看C#7.0加入的型別模式(Type Pattern):

這個不多說了,大家自己體會,單純的在Nullable下,可能體現的不是很清晰,個人認為這個小變動其實意義並不是很大,同樣場景下,或許if-if else-else會讓程式碼更清晰易讀些。

如果說模式匹配僅僅是完善了一下switch-case,那可真是太大才小用了,下面我們看一個好玩的。

Match表示式

雖然把match帶到C#中看起來並不是什麼大事,但是會引起的程式碼簡化還是非常爽的。

就像很多人說三元表示式(? : )將if-else簡化一樣。match表示式,是將switch-case結構簡化到了一個新限度。

看match表示式程式碼前,我們先來看一行略坑的三元表示式。

好吧,我承認我是故意讓你們抓狂的。^_^, 為了能穩住大家看完上面這行程式碼後的情緒,來一副match表示式消消火。

這兩種寫法效果上是等效的,有沒有非常乾淨清爽的感覺?寫過match表示式的碼農,應該再也不想回去巢狀 <*>?<*>:<*> 了。 (注:目前這種寫法還未確認,C#7.0釋出後可能會有略微變動

Is表示式

如果說上面兩個變化是“語法糖”,那麼is表示式可是要玩真的了。

說點題外話,其實對正規表示式熟悉的童鞋可能知道,本質上[模式匹配]和正規表示式要解決的問題邏輯類似,以一個確定的模式,來判斷或查詢一個確定的例項。只不過在正規表示式中,這裡說的”模式”是正規表示式,”例項”指字串。而[模式匹配]下,所針對的”例項”是物件,那麼”模式”,就可以理解成is表示式了。

舉個例子,比如你要查詢並列出 一組電子裝置中,所有iPhone的IMEI串號,我們在C#6.0中,會這樣做:

一個非常典型的傳統方法,沒什麼好說的。我們直接來看C#7.0 中 is表示式怎麼等效的實現這段邏輯:

如果你還是覺得這沒什麼,那麼,其實這個例子中,僅僅體現出模式匹配中的屬性模式

根據Doc:#patterns C#7.0會提供一下幾種匹配方式:

  • 型別模式
  • 常量模式
  • 變數模式
  • 萬用字元模式
  • 位置模式
  • 屬性模式

我們可以想象,如果模式匹配組合起來使用,會給現有的C#程式碼打來多大的便利和清靜。

Okay,說了這麼多,下面給大家一個相對完整的案例,自行體會。

案例

注1:模式匹配的部分高階feature,已經確認在C#7.0中移除,可能出現在後續C#版本中。(#10888)。

注2:目前(2016-06-15VS15的最新Preview下,模式匹配的部分語法依然無法使用。

注3:由於目前仍然未在Roslyn中Release,後期有變動的可能,本文中涉及的樣例程式碼以Mads Torgersen在#Build 2016上的演示的語法為準,本文涉及的案例有可能無法在VS15 RTM後正常使用,僅供參考。

  (當然,如果筆者樂意,會及時把後期得到確認的變更更新到本文中 ^_^!)

目前(2016年6月)C#7.0還未正式釋出,大家如果想體驗部分特性,可以去下載VS15預覽版,最終釋出的語法可能和本文中提及的有所不同,最新動態請大家關注Roslyn專案。

相關文章