這個世界上總是存在着很多奇妙的東西。然而,在這部分所介紹的擴展方法就是其中之一。從字面上看可能讀者很難猜透“擴展方法”是什麼意思。然而,看了下面的例子,就會感覺到非常的奇妙。
namespace ExtMethod
{
public classClass1
{
public String s ="bill";
}
public class Class2:Class1
{
}
public static class AnyClassName
{
public static String getName(this Class1 class1)
{
return class1.s+class1.s;
}
}
public partial class Form1:Form
{
private void button1_Click(object sender,EventArgs e)
{
Class1 c=new Class1();
MessageBox.Show(c.getName());
Class2 c=new Class2();
MessageBox.Show(c.getName());
}
}
}
看到上面的代碼,也許很多人會感到奇怪,在Class1和Class2中並沒有getName方法,怎麼在調用時出來個getName方法呢?實際上,這就是擴展方法的用法,從本質上說,擴展方法就是將靜態方法(必須聲明成static)插入到某個類和其子類中(也就是說,在這些類中可以使用在外部定義的靜態方法)。那麼要往哪個類中插入呢?這就要在定義靜態方法時指定了。大家可以看看getName方法的第一個參數,使用了this關鍵字,這就表明這個方法是一個擴展方法,後面的類型就是要插入該方法的類,在本例中是Class1,也就是說在Class1及其子類中都可以使用getName方法。上面的調用代碼也相當於下面的代碼:
Class2 c=new Class2();
MessageBox.Show(AnyClassName.getName(c));
但使用c.getName可能會更好一些,而且也降低了對靜態方法所在的類(AnyClassName)的依賴性。
在使用擴展方法時應注意以下幾點:
1. 擴展方法所在的類名可以是任意合法的類名。
2. 擴展方法所在的類必須和使用擴展方法的代碼在同一個命名空間裏,否則無法編譯通過。
3. 在本例中,Class1和Class2只能聲明成public,因爲AnyClassName被聲明爲public。如果AnyClassName不加修飾符,Class1和Class2也可以不加修飾符,當然,也可以被聲明爲public。也就是說,Class1和Class2必須有比AnyClassName具有更強的訪問性。如下面代碼所示:
classClass1
{
public String s="bill";
}
class Class2:Class1
{
}
static class AnyClassName //這時如果前面加public是無法編譯通過的。
{
public static String getName(this Class1 class1)
{
return class1.s+class1.s;
}
}
4. 如果在Class1或Class2中已經有getName方法了,那麼Class1或Class2中的getName優先級更高。也就是說,擴展方法是無法覆蓋原類中的同名(參數名和類型也相同)的方法的。
擴展方法尤其在很多類需要同樣的方法,而這些類又無法繼承其它類時特別有用。當然,在要對某個類進行擴展,但我們並沒有源代碼時,擴展方法也可以派上用場。