標籤:
前沿:
擴充方法使你能夠向現有類型“添加“方法,而無需建立新的衍生類別型、重新編譯或以其它方式修改原始類型。擴充方法是一種特殊的靜態方法,但可以像擴充類型上的執行個體方法一樣進行調用。
本文:
為了理解擴充方法,最佳的辦法就是看代碼,假如我們要定義一個下面這樣的IndexOf方法:
public static class StrignBuilderExtensions { public static int IndexOf(StringBuilder sb, char value) { for (int i = 0; i < sb.Length; i++) { if (sb[i] == value) return i; } return -1; } }
定義哈皮這個方法後,可以在代碼中使用它,如下所示:
StringBuilder sb = new StringBuilder("Hello,my name is"); int index = StrignBuilderExtensions.IndexOf(sb.Replace(‘,‘, ‘!‘), ‘!‘);
上述代碼看起來沒有什麼問題,但從程式員的角度看不是很理想。第一個問題是,要擷取一個StringBuilder中的某個字元的做索引,必須要知道StrignBuilderExtensions存在,第二個問題是,代碼沒有反映在StringBuilder對象上執行的操作的順序,使碼難寫、讀和維護。我們希望先調用Replace,再在調用IndexOf,但從左向右讀最後一行代碼,先看到的是IndexOf,然後才看到Replace。當然,可以下面這樣寫,事代碼的行為看起來容易理解。
sb.Replace(‘,‘, ‘!‘); int index = StrignBuilderExtensions.IndexOf(sb, ‘!‘);
但是這兩個版本都會影響我們對程式碼為的理解。StrignBuilderExtensions顯得“小題大做“,造成我們無法專註於當前要執行的操作,如果StringBuilder類內部定義了IndexOf方法,就可以將上述代碼重寫為:
int i = sb.Replace(‘,‘, ‘!‘).IndexOf(‘!‘);
有了這個例子做鋪墊,就很容易理解C#擴充方法所做的事情了。他允許你定義一個靜態方法,並且用執行個體方法的文法調用他。換言之,現在可以定義自己的IndexOf方法。同時避免出現上述問題,為了將IndexOf轉變成擴充方法,只需在第一個參數前加this關鍵字
public static class StrignBuilderExtensions { public static int IndexOf(this StringBuilder sb, char value) { for (int i = 0; i < sb.Length; i++) { if (sb[i] == value) return i; } return -1; } }
現在,當編譯器看到如下代碼:
int index=sb.IndexOf(‘x‘);
它首先檢查StringBuilder類或者他的任何基類是否提供了擷取單個Char參數,名為IndexOf的執行個體方法。如果存在這樣一個執行個體方法,編譯器會產生IL代碼來調用它。
如果沒有發現匹配的執行個體方法,則繼續檢查是否有任何靜態類定義了一個名為IndexOf的靜態方法,她的第一個參數是和當前調用方法的那個運算式的類型匹配的一個類型,而且這個類型必須使用this關鍵字來標示.
【C#】擴充方法