擴展方法解決問題:以往對已存在的類庫進行擴展,可行的方式直接對源代碼進行修改或者直接派生。
擴展方法注意事項:
擴展方法的使用范圍:
實例調用:
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;
}
}
}
推薦采用實例方法調用,編譯器實際上將實例調用編譯成靜態方法的調用。
擴展方法的地雷區:
因為編譯時,擴展方法的優先級總是比類型本身中定義的實例方法級別低,其實意思就是類中有一個具有相同簽名的擴展方法,編譯器總是綁定到該實例方法,當編譯器需要調用方法時,首先在該類型的實例方法中尋找匹配的方法。如果未找到任何匹配方法 ,編譯器將搜索為該類型定義的任何擴展方法,並且綁定到它找到得第一個擴展方法。