GPS平臺、網站建設、軟件開發、系統運維,找森大網絡科技!
http://cnsendnet.taobao.com
來自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=476php
擴展方法使你可以向現有類型「添加」方法,而無需建立新的派生類型、從新編譯或以其餘方式修改原始類型。 擴展方法是一種特殊的靜態方法,但能夠像擴展類型上的實例方法同樣進行調用。 以上是msdn官網對擴展方法的描述,如今我經過一個情景例子來對此進行闡釋。假設一個控制檯程序class Program{}裏面的主函數以下:編程
static void Main(string[] args)
{
DateTime now = DateTime.Now;
string time = now.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(time);
Console.ReadKey();
}網絡
假設需求變了,日期的顯示格式要變成"yyyy-MM-dd"這種格式,固然只須要初始化time時按下面寫法改寫便可:
string time = now.ToString("yyyy-MM-dd");
可是若是要改變日期格式的有不少個類呢?每一個都要改一次嗎?這樣一旦需求變來變去就忙死人了。傳統的解決方式是封裝一個幫助類,在裏面寫方法,而後供其餘類調用。
本例在當前項目模仿添加一個DateHelper類:public class DateHelper{},在類裏面定義方法:
public static string DateToString(DateTime dt)
{
return dt.ToString("yyyy-MM-dd HH:mm:ss");
}
因而原來的主函數改寫以下:運維
static void Main(string[] args)
{
DateTime now = DateTime.Now;
string time = DateHelper.DateToString(now);
Console.WriteLine(time);
Console.ReadKey();
}ide
此時若是變需求,只須要改寫DateHelp類裏的DateToString()方法就好了,無論有多少個類調用此方法,都會被影響。問題解決了,但是這樣要調用另外一個類的方法,仍是有點麻煩,有沒有什麼方法可以讓咱們像now.DateToString()同樣直接調用呢?固然DateTime是微軟寫好的,咱們改不了,沒法建立想要的實例方法,因而,便引出了擴展方法。
下面是擴展方法的要素:
1.此方法必須是一個靜態方法
2.此方法必須放在靜態類中
3.此方法的第一個參數必須以this開頭,而且指定此方法是擴展自哪一個類型
根據以上要素,咱們DateHelper類改爲靜態類:public static class DateHelper{} ,同時改寫DateToString()方法:
public static string DateToString(this DateTime dt)
{
return dt.ToString("yyyy-MM-dd HH:mm:ss");
}
此時回到主函數方法體,輸入"now."即可以看見自動提示有個DateToString()方法,因而代碼能夠這樣寫:函數
static void Main(string[] args)
{
DateTime now = DateTime.Now;
string time = now.DateToString();
Console.WriteLine(time);
Console.ReadKey();
}學習
顯而易見,這樣用起來會更加便捷,並且這樣讓咱們看起來確實就像是被擴展類型自己具備的實例方法同樣,可讀性很高。下面歸納一下擴展方法的特色:
1.擴展方法擴展自哪一個類型,就必須是此類型的變量來使用,其餘類型沒法使用,本例擴展自DateTime類型,就只能是被DateTime類型的變量.出來(now.DateToString())
2.擴展方法中的this後面的參數不屬於方法的參數,本例是無參數,this後面的DateTime dt是指明擴展方法擴展自何種類型
3.若是擴展方法和實例方法具備相同的簽名,則優先調用實例方法
4.擴展自父類上的方法,能夠被子類的對象直接使用
5.擴展自接口上的方法,能夠被實現類的對象直接使用
6.擴展方法最終仍是被編譯器編譯成:靜態類.靜態方法(),本例中now.DateToString()最終仍是會被編譯成DateHelper.DateToString(now),這是它的本質
實際上,咱們可能會遇到這樣的情景,如在接口擴展一個方法的時候,全部的本來已實現該接口的類都要實現新擴展的方法,這樣的改動是一個很麻煩的工做,可使用擴展方法「曲線救國」;而有時候咱們想爲某個類添加新方法卻不想改動這個類,那麼擴展方法這種「僞添加」方法的方式就體現出它的價值了。最多見的擴展方法是LINQ標準查詢運算符,運用普遍,這種方便快捷的方式理應博得碼農們點1024個贊。動畫
什麼是擴展方法?
擴展方法從字面上理解是指擴展的方法,而對應到面向對象編程這個格局中則是指爲一個類提供的擴展方法。按照咱們一般的理解,咱們首先須要得到某個類的源代碼,而後在這個類代碼中增長成員方法,這樣就能夠達到爲一個類提供擴展方法的目的。但是不幸地是,這種方法在沒有源代碼的狀況下就沒法奏效了,並且咱們人爲地去改變源代碼有可能會破壞整個代碼的穩定性。那麼有沒有一種方法能在不改變源代碼的前提下爲某個類提供擴展方法呢?這就是咱們今天要說的擴展方法,因此咱們能夠將擴展方法理解爲在不改變源代碼的前提下向外部提供擴展方法的一種方式。C#中的擴展方法實現起來是相對來講比較簡單的,例如咱們作在Unity3D遊戲開發的時候,可能會用到DOTween這個插件。這個插件是iTween的做者從新編寫一個動畫插件,效率上比iTween有較大的提高。更爲重要的一點是,它採用擴展方法這種實現方式,使得咱們在調用這些API接口的時候難以感受到咱們是在使用一個插件,更像是在使用Unity3D的原生函數,因此當咱們使用DOTween + uGUI 這樣的組合的時候,心裏會感到無比的舒暢,一切都像是水到渠成通常。
擴展方法有哪些特色?
擴展方法在實現上和普通的面向對象編程是同樣的,換句話說,咱們只須要定義一個類,而後在裏面添加並實現相應的方法便可。可是這裏須要注意的地方有三點,第一,實現擴展方法的類必須是靜態類且類的名稱和實現擴展方法的類無關;第2、實現擴展方法的類方法必須是靜態方法;第3、實現擴展方法的類方法的第一個參數必須是使用this關鍵字指明要實現擴展方法的類。例如,咱們知道將一個合法字符串類型轉換爲整型,可使用int.parse()方法,假如咱們但願爲string類型擴展一個ToInt方法應該怎麼辦呢?咱們一塊兒來看下面的這段代碼:網站
GPS平臺、網站建設、軟件開發、系統運維,找森大網絡科技!
http://cnsendnet.taobao.com
來自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=476this