重構成 C# 7 的 Local Function

Local Function 是 C# 7 支援 FP 的重要功能,除了比 C# 3 的 Func 與 Action 可讀性高,速度也更快,因此建議全面使用 Local Function 取代 Func 與 Action。

透過 Rider,我們也可將 legacy code 快速重構成有 FP 風格的 Local Function。

Version

macOS High Sierra 10.13.6
.NET Core 2.1
Rider 2018.1.3

重構前


Program.cs

local000

  1. 傳統我們在寫 LINQ 時,會將 Lambda 寫在 Where() 內,若能將 Lambda 抽成 Local Function,則可讀性更高

Introduce Variable


Program.cs

local001

  1. 選擇要抽的 Lambda

local002

  1. 按熱鍵 ⌃ + T,選擇 Introduce Variable

local002

  1. Rider 會自動抽出 Func,不過卻也建議你改用 Local Function

Q : 為什麼 Rider 不直接抽成 Local Function ?

local003

因為 Local Function 屬於 C# 7 支援的新功能,只有當你選擇 C# 7 以上時,才會建議使用 Local Function。

To Local Function


local005

  1. 將 cursor 放在 predicate
  2. 按熱鍵 ⌥ + ↩,選擇 To local function

local006

Rider 會將 Local Function 轉型成 Func,這是不需要的,Rider 也已經反灰提示這是多餘的。

  1. 將 cursor 放在反灰之處
  2. 按熱鍵 ⌥ + ↩,選擇 Remove redundant code in file

Rename Variable


local007

Rider 預設抽出的 Local Function 名稱都是 Predicate,可讀性不高,需要進一步重構

  1. 將 cursor 放在 Predicate
  2. 按熱鍵 ⌥ + ↩,選擇 Rename

local008

  1. 重新命名為 IsOdd

重構後


local009

如此的程式碼,可讀性就很高。

  1. original 陣列經過 Where() ,再經過 ForEach(),這正是 FP 所謂的 Function Pipeline
  2. Where(IsOdd) 可以明顯看出要 where 的是 奇數ForEach(WriteLine) 可以看出 writeline 要 foreach,而 WriteLine()IsOdd() 又各自是小小的 Local Function 構成,這正是 FP 所謂的 Function Composition

Conclusion


  • 要抽成 Local Function,直覺會想使用 Rider 的 Extract Method,但因為在 FP 觀念中,Function 就是 First-Class Value,所以在 Rider 要使用 Introduce Variable,而不是 Extract Method
2018-07-21