Extension Method(擴充功能)
相信大家在編寫程式的時候都會把一些通用的方法定義為靜態方法並放在自定義的靜態類別中。 因為這樣做的話, 就能在程式透過調用該類別方法來獲得你想要的結果。 如以下例子所示, 在一個名為EnumerableUtil 的類別中定義headThree 方法來拿取首3個元素。
在.net framework 3.5 之前的版本, 以上的編寫風格可為非常常見。 但在C#3.5 或之後的版本,
提供了另一種彈性更大的風格Extension Method(擴充方法) 為甚麼說它彈性比起Util風格更大呢??
從上例看到, 使用Extension Method(擴充功能) 的話, 只需在方法的第一個參數前加上this。 它的呼叫形式與物件呼叫實例方法一樣。 編程風格更與OOP(物件導向編程)相似。 在.net framework3.5 或以後的版本, 當物件呼叫實例方法時,編譯器會嘗試尋找類別是否有定義這方法, 若沒有的話,
則編譯器會再尋找現在執行的命名空間和導入的命名空間是否有定義這方法。 由於ExtensionMethodExample 命名空間中的EnumerableExtension 有定義headThree這方法。 所以沒有編譯錯誤。
另外一點是, 使用Extension Method(擴充功能) , 能讓程式的編寫更加簡潔。
例如 想要計算IEnumerable<int> 類型 的頭3個元素的差。 使用Util 的編程風格時, 會是以下這樣
先在EnumerableUtil 中定義 計算 差的方法
再調用該方法
例如 想要計算IEnumerable<int> 類型 的頭3個元素的差。 使用Util 的編程風格時, 會是以下這樣
先在EnumerableUtil 中定義 計算 差的方法
再調用該方法
上述中 data.headThree<int>().difference() 這種chaining 編程風格讓原本需要多行的程式簡化至數行。 所以說使用Extension Method(擴充功能) 來編寫公用方法的話彈性更大。
注意事項
使用Extension Method(擴充功能) 形式來建立共用的方法。 有幾點規則是需要注意的。
- 一定是靜態方法和不是泛型靜態類別
- 一定要有至少一個參數
- 第一個參數一定要有this 這個prefix
- 第一個參數不能是out 或ref 類
- 第一個參數類別不能是pointer
最後, 雖然在靜態方法中的第一個參數加上了this 來變成Extension Method(擴充功能) 但其實它的靜態特性是依然可以使用的。
所以IEnumerable<int> subdata3 = EnumerableExtension.headThree<int>(data);
這句是依然能成功編譯的。 不相大家可試試加在程式碼當中試試看。
以上例子的源代碼在 https://github.com/Isaac234517/C-_ExtensionMethodExample
留言
張貼留言