什麼是擴充套件方法?
擴充套件方法使您能夠向現有型別(或介面)「新增
」方法,而無需建立新的派生型別、重新編譯或以其他方式修改原始型別。擴充套件方法是一種特殊的靜態方法 ,但可以像擴充套件型別
上的例項方法一樣進行呼叫。對於用
c# 和
visual basic
編寫的客戶端**,呼叫擴充套件方法與呼叫在型別中實際定義的方法之間沒有明顯的差異。(源於
msdn)
(1)擴充套件方法的建立
首先需要定義乙個準備包含擴充套件方法的靜態類。
public class enlargeclass
其次,向該類新增乙個靜態的方法。
該方法的第乙個引數必須以
this
修飾符開頭。形參為
需要將該方法繫結到的型別。這一引數不需要使用者在呼叫處顯式提供。接下來的形參則根據方法需要新增。 如:
public static returntype methodname (this
clientclass refobj , //
由編譯器識別並填充
parametertype
parameter //
由呼叫者使用的引數 ……
) 注:
1. clientclass
表示你要繫結到的型別。編譯器根據這一型別來決定該方法繫結到那種型別上。
refobj
表示當前的物件。即呼叫者的例項的乙個引用。 2.
指示繫結到的型別的引數必須由
this
修飾。從這一點可以看出。
this
關鍵字表示了
enlargeclass
在當前的上下文的乙個引用。
注意:refobj
並不是乙個指向同一物件的指標。它是乙個原物件的引用複本,是否能夠影響到原物件取決於原物件的型別(引用或者值型別)。 3.
指示型別繫結的引數必須處於該方法的第乙個位置。
這樣編譯器不會關注下面的引數列表。否則將不能通過編譯。
4. 在建立擴充套件方法時,需要保證該方法對使用點是可訪問的。
5. 如果定義了乙個和原類成員相同的擴充套件方法,則編譯器優先於原型別方法。所以,編寫擴充套件方法時要注意不能和原類方法重名。
可以向.net
的所有型別和自定義的型別新增擴充套件方法。
在擴充套件方法的靜態類中,可以為多個型別繫結方法。
為什麼語言設計者要使用靜態形式繫結方法呢?和程式的入口
main
函式一樣,靜態的呼叫不容易受到對型別構造的考慮和影響。但程式設計者卻需要注意訪問許可權的修飾。
為了考察一下你的理解回答乙個問題。能不能將
string ,char,baty,int
等基本資料型別進行方法擴充套件?並解釋原因。
(2)擴充套件方法的呼叫
擴充套件方法的呼叫是使用原被擴充套件的型別的例項來呼叫的。從表面看,物件呼叫靜態方法是乎不合常理。事實上在被編譯器編譯為
il時會自動轉換為對擴充套件類靜態方法的呼叫。
擴充套件方法並不屬於原型別中的成員。它只是一種外接的功能。所以,擴充套件方法無法訪問原型別的內部私有成員。但擴充套件方法是否可以操作原類的公共屬性呢?根據上面的理解,你應該能很回答這個問題。如果還不清楚,請嘗試寫幾個小示例。答案就不用公布了。
呼叫乙個擴充套件方法的步驟如下:
首先需要使擴充套件類在當前環境下可見。如果擴充套件方法建立在其它命名空間,請引入該命名空間。
當引入擴充套件類的命名空間時,編譯器就會在檢查時對你所擴充套件的型別加入建立的靜態方法。事實上,系統並沒有真正的向原類新增任何函式成員。只是將當前可見的該型別產生的所有物件繫結了該方法。
例如:使用上面建立的擴充套件 假設
clientclass
類為.net
定義的int類
那麼,int32 myint=new int();
這樣,myint
就擁有了
methodname
方法。
myint. methodname(parameter);
呼叫即可。
其次,在這一型別的例項中像使用該型別定義的非靜態成員一樣使用它。
首先編譯器會查詢原型別的函式成員,如果沒有該函式簽名,則查詢擴充套件類的成員,因此,如果擴充套件方法與原類方法簽名相同,則系統將不會呼叫擴充套件方法。
擴充套件方法可以在原型別內部中像自己的函式成員一樣呼叫。原因是:雖然並沒有真正繫結到該型別上,但繫結了類的
this
指標指向的成員。例如測試示例中的
study
方法內部,就使用了擴充套件方法。
應用範圍:
除非在無法對原有類進行修改的情況下,否則
microsoft
不建議使用增加擴充套件的方法。應當使用繼承等方式進行型別擴充套件,以使系統達到良好清晰的結構。
最後留給乙個問題,能不能將擴充套件方法變為泛型方法?
[測試示例原始碼]
using
system;
using
system.collections.generic;
using
system.linq;
using
system.text;
namespace
consoleenlargeclassspace
//////擴充套件string 型別
///:用於比較兩個字串物件值是否相同。
///
///
///用於比較的字串物件
///bool
public
static
bool comparestring(this
string str,string aimstr)
//////
擴充套件int
///:用於得到int 物件的長度
///
///
///
public
static
int32 getlength(this
int32 myint)
//////
*測試引用和值型別的區別
//////
///
///
public
static
void sayname(this programspace.people people,string rename)
} }
namespace
programspace
} public
class
people
set }
public
void study(string rename)
} }
c 如何擴充套件型別的內建方法
c 3.0 vs2008 支援在任何型別上擴充套件生成自定義的方法。比如說想在string型別的物件裡面多乙個toint32 來方便的將字元轉換成整形。在實現的過程中的關鍵字為static和this 下面我們來做乙個在string型別中新建乙個toint32的自定義方法 public static ...
c 反射 判斷函式是否為擴充套件方法
c methodinfo內並沒有字段用來標識該方法是否為擴充套件方法。目前只能通過自己擴充套件來判斷方法是否為擴充套件方法,如下 static ienumerablegetextensionmethods assembly assembly,type extendedtype 核心 就一句 meth...
C 擴充套件方法
c 語言從3.0開始增加了乙個很特別的功能 擴充套件方法。那麼擴充套件方法起什麼作用呢?很多時候我們想為已經存在的類擴充套件某些功能,而又沒有必要去繼承該類,甚至有時候這個類根本就不允許繼承,如string類,這時候就可以使用擴充套件方法來為其擴充套件功能。下面舉例說明 一 我們建立乙個類庫如下 c...