寫在前面
系列文章
擴展方法
總結
上篇文章介紹了隱式類型,自動屬性,初始化器,匿名類的相關概念,及通過反編譯的方式查看了編譯器幫我們做了那些事。本篇文章將介紹擴展方法的知識點,及如何定義,如何使用的相關內容。
Linq之Lambda表達式初步認識
Linq之Lambda進階
Linq之隱式類型、自動屬性、初始化器、匿名類
擴展方法使你能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種特殊的靜態方法,但可以像擴展類型上的實例方法一樣進行調用。
最常見的擴展方法是 LINQ 標准查詢運算符,它將查詢功能添加到現有的 System.Collections.IEnumerable 和 System.Collections.Generic.IEnumerable<T> 類型。 若要使用標准查詢運算符,請先使用 using System.Linq 指令將它們置於范圍中。 然後,任何實現了 IEnumerable<T> 的類型看起來都具有 GroupBy、OrderBy、Average 等實例方法。 在 IEnumerable<T> 類型的實例(如 List<T> 或 Array)後鍵入“dot”時,可以在 IntelliSense 語句完成中看到這些附加方法。
首先看一下啊,擴展方法漲什麼樣子
通過上圖可以發現,擴展方法所在的類必須是靜態類,方法必須為靜態方法,並且方法第一個參數必須以this修飾符開始。
如何自定義擴展方法?
1.定義一個靜態類以包含擴展方法。 該類必須對客戶端代碼可見。
2.將該擴展方法實現為靜態方法,並使其至少具有與包含類相同的可見性。
3.該方法的第一個參數指定方法所操作的類型;該參數必須以 this 修飾符開頭。
4.在調用代碼中,添加一條 using 指令以指定包含擴展方法類的命名空間。
5.按照與調用類型上的實例方法一樣的方式調用擴展方法。
請注意,第一個參數不是由調用代碼指定的,因為它表示正應用運算符的類型,並且編譯器已經知道對象的類型。 您只需通過 n 為這兩個形參提供實參。
一個例子
為String擴展這樣一個方法:返回字符串的字節數。在項目中添加一個這樣的類StringExtension
1 namespace Wolfy.LinqDemo.Extensions 2 { 3 /// <summary> 4 /// string類型擴展方法 5 /// 靜態類 6 /// </summary> 7 public static class StringExtension 8 { 9 /// <summary> 10 /// 獲取字符串的字節數 11 /// </summary> 12 /// <param name="source">字符串</param> 13 /// <returns>字節長度</returns> 14 public static int GetBytesLength(this string source) 15 { 16 byte[] bytes = Encoding.Default.GetBytes(source); 17 return bytes.Length; 18 } 19 } 20 }
在使用時,首先引入你的擴展方法所在的靜態類所在命名空間,比如在這個例子中,需要引入
1 //首先引入命名空間 2 using Wolfy.LinqDemo.Extensions;
然後你就可以這樣來用,就好比你定義的這個方法就是string類中定義的一樣。
通過代碼也發現這樣的問題,擴展方法,在無法修改源代碼的情況下,提供了一種為該類來添加行為的方式。比如在這裡咱們無法修改string類的源代碼,也不可能在string類的方法中添加一個GetBytesLength的方法,但是通過擴展方法,在客戶端使用的時候,就好比,這個方法就是string類的方法一樣。
在鼠標放在方法名上時,也會提示該方法是擴展方法,如圖
輸出結果
1、擴展方法為靜態方法,所在的類必須為靜態類,方法第一個參數必須以this修飾符開頭。
2、擴展方法在使用的時,必須能夠訪問到。
3、在使用時需引入擴展方法所在的命名空間。(當然你也可以直接使用要擴展的類型的命名空間,比如string類型的命名空間為System,你可以使用System作為StringExtension的命名空間,這樣使用的時候不需要引入命名空間了。但一般不建議這樣做!)
參考文章
MSDN:http://msdn.microsoft.com/zh-cn/library/bb383977.aspx
http://msdn.microsoft.com/zh-cn/library/bb311042.aspx