擴展方法使你能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。擴展方法是一種特殊的靜態方法,但可以像擴展類型上的實例方法一樣進行調用。
下面的示例為String添加判斷輸入的string是否郵箱格式的功能。
using System.Text.RegularExpressions; namespace Extension_Method { //類必須為static的 public static class StringHelper { //擴展方法必須為靜態的 //擴展方法的第一個參數必須由this來修飾(第一個參數是被擴展的對象) public static bool isEmail(this string _string) { return Regex.IsMatch(_string, @"^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$"); } } }
調用測試部分:
string str = "czx@123.com";
Console.WriteLine(str.isEmail().ToString());這樣就為String擴展了判斷是否為郵箱的功能。
MSDN指出:擴展方法被定義為靜態方法,但它們是通過實例方法語法進行調用的。它們的第一個參數指定該方法作用於哪個類型,並且該參數以 this 修飾符為前綴。僅當你使用 using 指令將命名空間顯式導入到源代碼中之后,擴展方法才位於范圍中。
在代碼中,可以使用實例方法語法調用該擴展方法。但是,編譯器生成的中間語言 (IL) 會將代碼轉換為對靜態方法的調用。因此,並未真正違反封裝原則。實際上,擴展方法無法訪問它們所擴展的類型中的私有變量。通常,我們更多時候是調用擴展方法而不是實現你自己的擴展方法。由於擴展方法是使用實例方法語法調用的,因此不需要任何特殊知識即可從客戶端代碼中使用它們。若要為特定類型啟用擴展方法,只需為在其中定義這些方法的命名空間添加 using 指令。
可以使用擴展方法來擴展類或接口,但不能重寫擴展方法。與接口或類方法具有相同名稱和簽名的擴展方法永遠不會被調用。編譯時,擴展方法的優先級總是比類型本身中定義的實例方法低。換句話說,如果某個類型具有一個名為 Process(int i) 的方法,而你有一個具有相同簽名的擴展方法,則編譯器總是綁定到該實例方法。當編譯器遇到方法調用時,它首先在該類型的實例方法中尋找匹配的方法。如果未找到任何匹配方法,編譯器將搜索為該類型定義的任何擴展方法,並且綁定到它找到的第一個擴展方法。
擴展方法准則:在使用擴展方法來擴展你無法更改其源代碼的類型時,你需要承受該類型實現中的更改會導致擴展方法失效的風險。
如果你確實為給定類型實現了擴展方法,請記住以下幾點:
-
如果擴展方法與該類型中定義的方法具有相同的簽名,則擴展方法永遠不會被調用。
-
在命名空間級別將擴展方法置於范圍中。例如,如果你在一個名為 Extensions 的命名空間中具有多個包含擴展方法的靜態類,則這些擴展方法將全部由 using Extensions; 指令置於范圍中。
