擴展方法解決問題:以往對已存在的類庫進行擴展,可行的方式直接對源代碼進行修改或者直接派生。
擴展方法注意事項:
擴展方法的使用范圍:
實例調用:
namespace ExtensionMethodObjects { //1,定義一個靜態類 public static class ExtensionMethods { //2,定義一個靜態方法,該方法擴展object對象。 /* * 擴展方法的的參數部分:第一個參數必須為THIS * 然後跟隨要擴展的類型名稱和標識值 */ public static void SayHello(this object obj) { Console.WriteLine("擴展方法!"); } } }
namespace ExtensionMethodObjects { class Program { static void Main(string[] args) { //實例化一個object類型的對象 object o = new object(); o.SayHello(); } } }
擴展方法後,不用對原來的程序集進行任何改動。
靜態調用:
namespace InvokeExtensionMethods { //注意類的可見性級別,必須要在整個應用程序范圍可見。 public static class ExtensionMethods { //擴展int類型,為其添加一個反轉整數的能力。 public static int ReverseDigits(this int i) { char[] digits = i.ToString().ToCharArray(); Array.Reverse(digits); string newDigits = new string(digits); return int.Parse(newDigits); } //擴展Car類,為其添加一個SpeedDown方法 public static int SpeedDown(this Car car) { //這樣寫將會產生一個編譯時錯誤 //return --Speed; //正確的方法應該是car.Speed; return --car.Speed; } } }
namespace InvokeExtensionMethods { class Program { static void Main(string[] args) { int i = 123456; //實例方法調用,直接用擴展的類的對象實例來進行調用 Console.WriteLine("實例方法調用,反轉後的值為:{0}", i.ReverseDigits()); //靜態方法調用,通過調用擴展方法的靜態類名再加擴展方法進行調用 Console.WriteLine("靜態方法調用,反轉後的值為:{0}", ExtensionMethods.ReverseDigits(i)); } } //定義一個簡單的汽車類 public class Car { public int Speed; public int SpeedUp() { return ++Speed; } } }
推薦采用實例方法調用,編譯器實際上將實例調用編譯成靜態方法的調用。
擴展方法的地雷區:
因為編譯時,擴展方法的優先級總是比類型本身中定義的實例方法級別低,其實意思就是類中有一個具有相同簽名的擴展方法,編譯器總是綁定到該實例方法,當編譯器需要調用方法時,首先在該類型的實例方法中尋找匹配的方法。如果未找到任何匹配方法 ,編譯器將搜索為該類型定義的任何擴展方法,並且綁定到它找到得第一個擴展方法。