c 擴充套件方法詳解

2021-10-07 05:07:06 字數 4998 閱讀 9347

擴充套件方法被定義為靜態方法,但它們是通過例項方法語法進行呼叫的。 它們的第乙個引數指定該方法作用於哪個型別,並且該引數以 this 修飾符為字首。 擴充套件方法當然不能破壞物件導向封裝的概念,所以只能是訪問所擴充套件類的public成員。

擴充套件方法使您能夠向現有型別「新增」方法,而無需建立新的派生型別、重新編譯或以其他方式修改原始型別。擴充套件方法是一種特殊的靜態方法,但可以像擴充套件型別上的例項方法一樣進行呼叫。

c#擴充套件方法第乙個引數指定該方法作用於哪個型別,並且該引數以 this 修飾符為字首。

擴充套件方法的目的就是為乙個現有型別新增乙個方法,現有型別既可以是int,string等資料型別,也可以是自定義的資料型別。例如為資料型別的新增乙個方法的理解:一般來說,int資料型別有個tostring的方法,就是把int 資料轉換為字串的型別,比如現在我們想在轉換成字串的時候還新增一點東西,比如增加乙個字元 a .那麼之前的tostring就不好使了,因為它只是它我們的int資料轉換為string型別的,卻並不能新增乙個字母 a.所以這就要用到所謂的擴充套件方法了。首先我們看乙個給現有的型別增加乙個擴充套件方法。我們想給string 型別增加乙個add方法,該方法的作用是給字串增加乙個字母a.

例項1:

//必須是靜態類才可以新增擴充套件方法

static class program

//宣告擴充套件方法

//擴充套件方法必須是靜態的,add有三個引數

//this 必須有,string表示我要擴充套件的型別,stringname表示物件名

//三個引數this和擴充套件的型別必不可少,物件名可以自己隨意取如果需要傳遞引數,//再增加乙個變數即可

public static string add(this string stringname)

}我們再來嘗試給我們自定義的型別增加乙個擴充套件方法,並增加乙個傳遞的引數。

例項2:

首先我們宣告乙個student類,它包含了兩個方法stuinfo,getstuinfo.例項**如下:

public class student

public  string getstuinfo(string stuname, string stunum)

\n" + "學號:", stuname, stunum);}}

之後我們再宣告乙個名為extensionstudentinfo的靜態類,注意必須為靜態。這個類的作用就是包含一些我們想要擴充套件的方法,在此我們宣告兩個student型別的擴充套件方法,student型別為我們自定義的型別。示例**如下:

public static class extensionstudentinfo

//宣告擴充套件方法

//要擴充套件的方法必須是靜態的方法,add有三個引數

//this 必須有,string表示我要擴充套件的型別,stringname表示物件名

//三個引數this和擴充套件的型別必不可少,物件名可以自己隨意取如果需要傳遞引數,在此我們增加了兩個string型別的引數

public static string extensiongetstuinfo(this student student, string stuname, string stunum)

}以上的工作做完之後便可以使用我們的擴充套件方法了,注意必須要用物件來呼叫擴充套件方法。

static void main(string args)

例項3、使用tagbuilder類建立擴充套件方法

上面自定義的span()方法十分簡單, 但是有時候我們要構造具有複雜結構的html元素, 如果用字串拼接的方法就有些笨拙.asp.net mvc框架提供了乙個幫助我們構造html元素的類:tagbuilder

tagbuilder類有如下方法幫助我們構建html控制項字串:

方法名稱    用途

addcssclass()    新增class=」」屬性

generateid()    新增id,  會將id名稱中的"."替換為idattributedotreplacement 屬性值的字元.預設替換成"_"

mergeattribute()    新增乙個屬性,有多種過載方法.

setinnertext()    設定標籤內容, 如果標籤中沒有再巢狀標籤,則與設定innerhtml 屬性獲得的效果相同.

tostring()    輸出html標籤的字串, 帶有乙個引數的過載可以設定標籤的輸出形式為以下列舉值:

tagrendermode.normal -- 有開始和結束標籤

tagrendermode.starttag -- 只有開始標籤

tagrendermode.endtag -- 只有結尾標籤

tagrendermode.selfclosing -- 單標籤形式,如

同時乙個tagbuilder還有下列關鍵屬性:

屬性名稱    用途

attributes    tag的所有屬性

idattributedotreplacement    新增id時替換"."的目標字元

innerhtml    tag的內部html內容

tagname    html標籤名, tagbuilder只有帶乙個引數-tagname的建構函式.所以tagname是必填屬性

下面在新增乙個自定義的htmlhelper類擴充套件方法,同樣是輸出乙個標籤:

public static string span(this htmlhelper helper, string id, string text, string css, object htmlattributes)

在頁面上,呼叫這個方法:

<% =html.span("span.test", "使用tagbuilder幫助構建擴充套件方法", "colorred", new )%>

生成的html**為:

使用tagbuilder幫助構建擴充套件方法

例項4(1)、擴充套件方法

//宣告擴充套件方法的步驟:類必須是static,方法是static,

//第乙個引數是被擴充套件的物件,前面標註this。

//使用擴充套件方法的時候必須保證擴充套件方法類已經在當前**中using

namespace 擴充套件方法

//帶多個引數的擴充套件方法

//在原始字串前後加上指定的字元

public static string quot(this string _input, string _quot)}}

(2)、使用方法

namespace 擴充套件方法}}

例項5:(注意使用il反編譯工具eg.  ilspy)

string str = "abc";

object len = str.getvaluebyname("length");

string型別現在有了getvaluebyname這個方法一樣,但實際上string並沒有這樣乙個方法。那這又是為什麼呢?是我們可愛的編譯器在其中做了手腳。為了避開編譯器的干擾,我們來看msil反編譯後:

l_0008: ldstr "length"

l_000d: call object testlambda.propertyextension::getvaluebyname(object, string)

從反編譯結果展示:

**編譯後和呼叫靜態方法沒有任何的差別(從call指令來看,這是在呼叫乙個靜態方法)。從這裡可以知道擴充套件方法即可以使用例項呼叫的方式也可以直接使用靜態類呼叫的方式。

str.getvaluebyname("length");

propertyextension.getvaluebyname(str,"length");

下面將對擴充套件方法做一些細節的介紹:

visual studio對擴充套件方法有智慧型感知的支援,如下圖:

在方法的圖示上有乙個與其他的都不相同,他的突變下面還帶有乙個藍色的向下的箭頭,這就表明這個方法是乙個擴充套件方法。

總結:在我們的程式設計生涯中我們要使用很多很多類庫,這些類庫有的是我們自己開發的,我們有她的**,有的是第三方發布的,我們不僅沒有他們的**,連看的機會都沒有。

作為.net程式設計師,我們每天都要和bcl(base class linbrary)打交道。無疑,bcl做為乙個年輕的框架類庫,她是成功的,但是還有一些時候我們還是得寫一些」helper」方法來擴充套件類庫,由於我們不能修改類庫的源**,我們只有寫乙個個的靜態類。雖然在使用上也算方便,但作為追求完美的程式設計師來說總有些**。 現在我就碰到這樣的事情,前兩天奉命寫乙個從xml檔案載入chart圖的設定的方法,從xml載入資料繫結到物件上,這肯定是反射的用武之地了。我經常需要寫一些根據物件屬性名字來判斷這個物件是否有這個屬性或者根據屬性名獲取該屬性的值。還是按照平常一樣,我很快寫了乙個propertyhelper,裡面有兩個靜態方法:hasproperty,getvaluebyname。

propertyhelper.hasproperty(point, "x"),如此的呼叫也還過得去,不過在c# 3.0微軟為我們提供了擴充套件方法。現在我們可以直接這樣呼叫了point.hasproperty(「x」);看看我是如何實現這個擴充套件方法的?

public static class propertyextension

type t = self.gettype();

propertyinfo p = t.getproperty(propertyname);

return p.getvalue(self, null);}}

我給object型別新增了乙個擴充套件方法,在.net裡所有的類都繼承自object,那所有的類都預設的擁有這個方法了,真方便,呵呵。注意到和普通的靜態方法有何差別?在這個方法的第乙個引數前面多了乙個this關鍵字。

在擴充套件的時候也不要對比較高層的類進行擴充套件,像對object的擴充套件我覺得就是不可取的,object是所有類的基類,一經擴充套件,所有的類都被「汙染」了。

擴充套件方法:

1 方法所在的類必須是靜態的

2 方法也必須是靜態的

3 方法的第乙個引數必須是你要擴充套件的那個型別,比如你要給int擴充套件乙個方法,那麼第乙個引數就必須是int。

4 在第乙個引數前面還需要有乙個this關鍵字。

5、擴充套件方法有就近原則,也就是如果在你的程式裡有兩個一模一樣的擴充套件方法,乙個和你的使用類是處於同一命名空間裡,另外乙個處於別的命名空間裡,這個時候會優先使用同一命名空間裡的擴充套件方法,也就是說「血緣關係」越近,越被青睞。

C 的擴充套件方法詳解

必須是靜態類才可以新增擴充套件方法 static class program 宣告擴充套件方法 擴充套件方法必須是靜態的,add有三個引數 this 必須有,string表示我要擴充套件的型別,stringname表示物件名 三個引數this和擴充套件的型別必不可少,物件名可以自己隨意取如果需要傳遞...

C 中的擴充套件方法詳解

擴充套件方法使你能夠向現有型別 新增 方法,而無需建立dezevgimo新的派生型別 重新編譯或以其他方式修改原始型別。擴充套件方法是一種特殊的靜態方法,但可以像擴充套件型別上的例項方法一樣進行呼叫。以上是msdn官網對擴充套件方法的描述,現在我通過乙個情景例子來對此進行闡釋。假設乙個控制台程式cl...

C 擴充套件方法和靜態類詳解

1.靜態方法屬於類,而普通方法則屬於物件,因此靜態方法可以用類名.靜態方法 來呼叫,而普通方法則必須用new來例項化後呼叫 2.靜態類中只能有 靜態的方法,屬性和變數 3.普通類中能有普通方法,也能有靜態類。在呼叫裡面的靜態方法時,可以使用普通類名.靜態方法來呼叫,不需要例項化類 擴充套件方法 擴充...