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

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

關(guān)于擴(kuò)展方法,需要留意的原則和規(guī)則

2019-11-17 02:23:30
字體:
供稿:網(wǎng)友

關(guān)于擴(kuò)展方法,需要留意的原則和規(guī)則

  • C#只支持?jǐn)U展方法,不支持?jǐn)U展屬性、擴(kuò)展事件、擴(kuò)展操作符
  • 擴(kuò)展方法必須在非泛型的靜態(tài)類中聲明,而且擴(kuò)展方法至少要有一個(gè)參數(shù),而且只有第一個(gè)參數(shù)能用this關(guān)鍵字標(biāo)記
  • C#在靜態(tài)類中查找方法時(shí),要求靜態(tài)類本身必須具有文件作用域,即擴(kuò)展方法必須在頂級(jí)靜態(tài)類中定義,而不能在嵌套的靜態(tài)的類中的定義
  • 由于靜態(tài)類可以取任何名字,所以C#編譯器要花一定的時(shí)間來尋找擴(kuò)展方法,它必須檢查文件作用域中的所有靜態(tài)類,并掃描他們的所有靜態(tài)方法來查找一個(gè)匹配;

我可不可以這樣理解,性能只是在編譯時(shí)有損失,編譯之后就和普通的靜態(tài)方法調(diào)用一樣了,沒有任何區(qū)別,之所以能得出這個(gè)結(jié)論是因?yàn)橥ㄟ^比較如下的兩種調(diào)用方式和對(duì)應(yīng)的IL代碼:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Extention{    class PRogram    {        static void Main(string[] args)        {            var dt = DateTime.Now;            var dtString = dt.DT();            var dtString1 = Extention.Extention1.DT(dt);            var dtString2 = Extention.Extention1.DT1(dt);            Console.ReadLine();        }    }    public static class Extention1    {        public static string DT(this DateTime dt)        {            return dt.ToString();        }        public static string DT1(DateTime dt)        {            return dt.ToString();        }    }}

 Main函數(shù)中對(duì)DT的三種調(diào)用生成的IL代碼如下:

 

C#編譯器是如何快速的定位擴(kuò)展方法的匹配的呢?


在C#中,一旦用this關(guān)鍵詞標(biāo)記了某個(gè)靜態(tài)方法的第一個(gè)參數(shù),編譯器就會(huì)在內(nèi)部向該方法應(yīng)用一個(gè)定制特性ExtensionAttribute;

另外,任何靜態(tài)類只要包含至少一個(gè)擴(kuò)展方法,它的元數(shù)據(jù)也會(huì)應(yīng)用這個(gè)特性,類似的,程序集中只要包含了至少一個(gè)符合上述特點(diǎn)的靜態(tài)類,它的元數(shù)據(jù)中也會(huì)應(yīng)用這個(gè)特性,

這樣一來,如果代碼調(diào)用了一個(gè)不存在的實(shí)例方法,編譯器就能快速的掃描引用的所有程序集,判斷他們哪些包含了擴(kuò)展方法,然后在這些程序集中,可以只掃描包含了擴(kuò)展方法的靜態(tài)類,

在每個(gè)這樣的靜態(tài)類中,可以只掃描擴(kuò)展方法來查找匹配,利用這些技術(shù),代碼能以最快的速度編譯完畢;

.class public auto ansi abstract sealed beforefieldinit Extention.Extention1extends [mscorlib]System.Object{.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (01 00 00 00)// Methods.method public hidebysig static string DT (valuetype [mscorlib]System.DateTime dt) cil managed {.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (01 00 00 00)// Method begins at RVA 0x2088// Code size 19 (0x13).maxstack 1.locals init ([0] string CS$1$0000)IL_0000: nopIL_0001: ldarga.s dtIL_0003: constrained. [mscorlib]System.DateTimeIL_0009: callvirt instance string [mscorlib]System.Object::ToString()IL_000e: stloc.0IL_000f: br.s IL_0011IL_0011: ldloc.0IL_0012: ret} // end of method Extention1::DT.method public hidebysig static string DT1 (valuetype [mscorlib]System.DateTime dt) cil managed {// Method begins at RVA 0x20a8// Code size 19 (0x13).maxstack 1.locals init ([0] string CS$1$0000)IL_0000: nopIL_0001: ldarga.s dtIL_0003: constrained. [mscorlib]System.DateTimeIL_0009: callvirt instance string [mscorlib]System.Object::ToString()IL_000e: stloc.0IL_000f: br.s IL_0011IL_0011: ldloc.0IL_0012: ret} // end of method Extention1::DT1} // end of class Extention.Extention1
  • 多個(gè)靜態(tài)類可以定義相同的擴(kuò)展方法,如果編譯器檢測(cè)到存在兩個(gè)或多個(gè)擴(kuò)展方法,就會(huì)提示調(diào)用不明確,此時(shí)需要調(diào)用靜態(tài)方法語法的方式來代替實(shí)例方法語法
  • 用一個(gè)擴(kuò)展方法擴(kuò)展一個(gè)類型時(shí),同時(shí)也擴(kuò)展了派生類,所以不要將Object作為擴(kuò)展方法的第一個(gè)參數(shù),否則這個(gè)方法在所有表達(dá)式上都能調(diào)用
  • 擴(kuò)展方法存在版本控制問題(為同一個(gè)類型定義兩個(gè)相同的擴(kuò)展方法,后來者會(huì)把前面的覆蓋掉,導(dǎo)致行為不一致)

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 江北区| 石嘴山市| 察雅县| 茶陵县| 木兰县| 白水县| 阿克陶县| 和硕县| 广汉市| 霍邱县| 东乌珠穆沁旗| 炎陵县| 安康市| 济宁市| 三台县| 大连市| 祁阳县| 独山县| 蒲江县| 宜昌市| 嘉兴市| 镇赉县| 乐陵市| 永安市| 林州市| 宁陕县| 高碑店市| 太原市| 扎囊县| 天津市| 广宁县| 德保县| 札达县| 汉源县| 泌阳县| 克山县| 堆龙德庆县| 什邡市| 南漳县| 渭南市| 漳州市|