国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

.NET擴展方法(一)

2019-11-14 16:28:24
字體:
供稿:網(wǎng)友

我還記得剛剛學編程的時候,老師經(jīng)常會提到一句話:注意空指針。所以經(jīng)常在某些“入口”位置,進行代碼校驗,空指針的判斷就是其中的一項工作。

string類型作為常用的數(shù)據(jù)類型,它在項目中出現(xiàn)的機率極高,所以往往會有如下的代碼片段:

            // str 是 string 類型            if (str == null || str == string.Empty)            {                // ... 其他操作                return;            }

每次都寫兩個雙等號判斷,著實有點煩人,讓人苦惱不已。在接下來的一段時間內(nèi)有幸發(fā)現(xiàn)了一種新的寫法:

            // str 是 string 類型            if (string.IsNullOrEmpty(str))            {                // ... 其他操作                return;            }

可是有些地方還要判斷是否為空格...

            // str 是 string 類型            if (String.IsNullOrEmpty(str) || str.Trim().Length == 0)            {                // ... 其他操作                return;            }

代碼長度又變長了...慢著,別急,.NET 4.0來了...

            // str 是 string 類型            if (String.IsNullOrWhiteSpace(str))            {                // ... 其他操作                return;            }

該方法很強大,不僅可以判斷空格,而且可以判斷制表符 '/t' 等空白字符。

可是... 可是... 我還是覺得不舒服,如果能實現(xiàn)下面的效果該多好呢。

            string str = null;            bool result = str.IsEmpty();            Console.WriteLine(result); // 正常編譯通過,正常運行不發(fā)生異常,并且輸出 True

假設(shè),我們已經(jīng)通過某些手段使string對象擁有IsEmpty方法:

如果IsEmpty是實例化方法,str對象為null,此時調(diào)用方法必定會引發(fā)空指針異常。

如果IsEmpty是靜態(tài)方法,按照語法規(guī)則,對象是無法調(diào)用靜態(tài)方法的。

所以,這條路好像行不通啊,怎么辦呢?——讓擴展方法來解決吧。

 

C#編程指南——擴展方法,給出的說明:擴展方法使你能夠向現(xiàn)有類型“添加”方法,而無需創(chuàng)建新的派生類型、重新編譯或以其他方式修改原始類型。

擴展方法是一種特殊的靜態(tài)方法,但可以像擴展類型上的實例方法一樣進行調(diào)用。

看樣子擴展方法很強大啊,那我們該如何實現(xiàn)和調(diào)用自定義的擴展方法呢?

1、因為擴展方法是向現(xiàn)有類型“添加”方法,所以必須有一個類型,這里就是我們想要添加方法的string類型了。

2、擴展方法也是方法,方法總是需要“載體”的,所以我們需要一個類。對該類的要求有且僅有兩點:

1)是頂級非泛型靜態(tài)類,2)是對于客戶代碼而言要有足夠的訪問權(quán)限。

3、對于擴展方法的要求有四點,除了是靜態(tài)方法和對于客戶代碼而言擁有足夠的訪問權(quán)限之外,還要求:

1)擴展方法的第一個參數(shù)必須是將要擴展的類型,這里就是string類型了。2)有且僅有第一個參數(shù)必須以this修飾符開頭。

4、寫完擴展方法,引入相應(yīng)的命名空間(如果需要),根據(jù)VS的智能敏感提示,然后寫代碼調(diào)用即可。 

 

Demo:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MethodDemo{    public static class StringExtentsion    {        public static bool IsEmpty(this string str)        {            return string.IsNullOrWhiteSpace(str);        }    }    class PRogram    {        static void Main(string[] args)        {            string[] arr = new string[] { null, string.Empty, " ", "  /t  ", "   /r/n   " };            foreach (string str in arr)            {                bool result = str.IsEmpty();                Console.WriteLine(result); // 編譯通過,運行無異常,并且全部輸出True            }                        Console.Read();        }    }}

  

讓我們仔細看一下這個demo吧,哇塞,對象竟然可以調(diào)用靜態(tài)方法了,這完全打破了以往的語法規(guī)則啊。是這樣嗎?讓我們以懷疑的心態(tài)一探究竟。

我們利用 VS自帶的IL反匯編程序,反編譯一下,看一看MSIL代碼。StringExtentsion類的IsEmpty方法簽名如下:

.method public hidebysig static bool  IsEmpty(string str) cil managed {} 
我們可以從中找到熟悉的影子 public static bool IsEmpty(string str){},它和一個標準的靜態(tài)方法無異,this 修飾符在這時候已經(jīng) “消失” 了。

 再看一下客戶代碼吧:

  IL_003b:  call       bool MethodDemo.StringExtentsion::IsEmpty(string)

 即便你看不懂MSIL代碼,我想你也有可能推測出正確結(jié)果——沒錯,我們被編譯器“欺騙”了,以下兩種寫法是等效的:

     result = str.IsEmpty();     result = StringExtentsion.IsEmpty(str); // 此時 擴展方法中的this修飾符是可有可無的

  

 看到這里,對擴展方法已經(jīng)有了一個大概了解,我們再回頭看一下 C#編程指南——擴展方法,中給出的一句說明:

擴展方法使你能夠向現(xiàn)有類型“添加”方法,而無需創(chuàng)建新的派生類型、重新編譯或以其他方式修改原始類型。擴展方法是一

種特殊的靜態(tài)方法,但可以像擴展類型上的實例方法一樣進行調(diào)用。

1、在這里“添加”兩個字被加了雙引號,故名其意不是真正的添加,擴展方法還存在于其定義的靜態(tài)類中,編譯后的方法簽名和標準的靜態(tài)方法無差異,

this修飾符、在這時候已經(jīng)消失了。

2、擴展方法是一種特殊的靜態(tài)方法,其特殊在于其語法規(guī)則可保證編譯器可以將“擴展類型的對象調(diào)用靜態(tài)方法(擴展方法)”這種語法表象 編譯通過。 

  可以想象一下,編譯器在編譯的時候,它要查找當前代碼文件域所引入的命名空間下的所有擴展方法、其工作量是很大的(更多參見:ExtensionAttribute)。

 

 

后記:

1、這次舉的這個例子很特殊,能將擴展方法的絕對威力展示出來:

1)string是.NET 類庫中的類,我們不能修改string類吧。

2)string是密封類,不能繼承。

3)避免空指針異常,按語法規(guī)則最便捷的方式就是通過靜態(tài)方法的參數(shù)去解決,就像 string.IsNullOrWhiteSpace 方法一樣,

可是想得到的形式卻是對象調(diào)用實例方法。

 

 2、如果給object添加一個擴展方法會出現(xiàn)什么效果呢?(未完待續(xù)...)

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 得荣县| 余姚市| 济阳县| 马鞍山市| 淮南市| 南阳市| 石台县| 中卫市| 永胜县| 辉县市| 岐山县| 娄烦县| 西青区| 兴化市| 青川县| 焦作市| 海安县| 法库县| 吴忠市| 万州区| 霞浦县| 宜君县| 本溪市| 洮南市| 宜城市| 志丹县| 巴彦淖尔市| 依安县| 湄潭县| 尼木县| 札达县| 石渠县| 金堂县| 荆门市| 张家川| 阿巴嘎旗| 都江堰市| 克山县| 手游| 昌图县| 手游|