我們說在C#3.0中,引入了一些列新的特性,但是個人認為Extension Method 這個特性是最爽的,最有創新的。
它真正的解決了:在保持現有Type原封不動的情況下對其進行擴充,你可以 在對Type的定義不做任何變動的情況下,為之添加所需的方法成員。下面我就來 講講。
C#3.X出來之前
大家都知道javascript有個特新Prototype,它就如同C#3.X中的Extension Method。這裡不多將了。
我們主要看看.NET的實現。在C#3.X出來之前我們可以做到對Type進行擴充。
interface的情況:
1public interface IEmployee
2{
3 string Name { get; set; }
4 int Age{get; set;}
5 int add(int n);
6}
對這個Interface進行擴充,為之添加一個Add方法執行相關的運算。我們唯 一的解決方案就是直接在這個Interface中添加一個Add成員。如上。實現了這個 Interface的Type必須實現該Interface的所有方法。所以,我們添加了Add這個 方法,將導致所有實現它的Type的重新定義和編譯,在很多情況下,我們根本不 需要這樣。
Class的情況:
如果我們將一個class作為基類,在基類中添加一個Add Method,所有的 Child Class都不會受到影響。但是在很多情況下,對於我們需要擴充的 Interface或者是class,我們是完全不能做任何改動。比如,我們要對datagrid 控制項進行擴充。我們常用的方法就自訂一個Class去繼承這個datagrid,將需 要添加的成員定義在我們自己定義的Class中,這就是我們常說的自訂控制項, 如果對於一個Sealed Class又該如何呢?我們要求的是對這個不能變動的Type進 行擴充,也就是使這個不能變動的Type的Instance具有我們添加的對象。
如果聽到這樣的要求:我們要對一個Type或者Interface進行擴充,卻不允許 我們修改它。這個要求確實有點苛刻。但是c#3.x 中我們可以選擇Extension Method。Extension Method本質上是在被擴充的對象執行個體上可以調用的靜態函數 ,不是繼承,所以不同於普通的成員函數,擴充函數不能直接存取被擴充項物件的 成員。只能通過該對象的執行個體來訪問。
C#3.X出來之後
簡單地說Extension Method是一個定義在Static Class的一個特殊的Static Method。之所以說這個Static Method特別,是因為Extension Method不但能 按照Static Method的文法進行調用,還能按照Instance Method的文法進行調用 。
我們還是先來看例子:
public static class MyExtensionMethods
{
// this代表擴充方法應用於string類型上
public static int ToInt32(this string s)
{
int i;
Int32.TryParse(s, out i);
return i;
}
}
public static void fnExtensionMethod()
{
string s = "27";
// 使用string的ToInt32()擴充方法
int i = s.ToInt32();
}
我們可以看看上面的例子,我們知道net framework 裡string是個Sealed 類 型,我們只能使用Extension Method來對其進行擴充。我們可以看看它的定義方 式。ToInt32是一個Static方法。和一般的Static方法不同的是:在第一個參數 前添加了一個this 關鍵字。這是在C# 3.0中定義Extension Method而引入的關 鍵字。添加了這樣一個關鍵字就意味著在調用該方法的時候這個標記有this的參 數可以前置,從而允許我們向調用一般Instance Method的方式來調用這個 Static Method。注意:需要在(只需要在)第一個參數前面使用this修飾。