分享
 
 
 

关于扩展方法,需要留意的原则和规则

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: |||超大  

关于扩展方法,需要留意的原则和规则

C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符扩展方法必须在非泛型的静态类中声明,而且扩展方法至少要有一个参数,而且只有第一个参数能用this关键字标记C#在静态类中查找方法时,要求静态类本身必须具有文件作用域,即扩展方法必须在顶级静态类中定义,而不能在嵌套的静态的类中的定义由于静态类可以取任何名字,所以C#编译器要花一定的时间来寻找扩展方法,它必须检查文件作用域中的所有静态类,并扫描他们的所有静态方法来查找一个匹配; 我可不可以这样理解,性能只是在编译时有损失,编译之后就和普通的静态方法调用一样了,没有任何区别,之所以能得出这个结论是因为通过比较如下的两种调用方式和对应的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函数中对DT的三种调用生成的IL代码如下:

C#编译器是如何快速的定位扩展方法的匹配的呢?

在C#中,一旦用this关键词标记了某个静态方法的第一个参数,编译器就会在内部向该方法应用一个定制特性ExtensionAttribute;

另外,任何静态类只要包含至少一个扩展方法,它的元数据也会应用这个特性,类似的,程序集中只要包含了至少一个符合上述特点的静态类,它的元数据中也会应用这个特性,

这样一来,如果代码调用了一个不存在的实例方法,编译器就能快速的扫描引用的所有程序集,判断他们哪些包含了扩展方法,然后在这些程序集中,可以只扫描包含了扩展方法的静态类,

在每个这样的静态类中,可以只扫描扩展方法来查找匹配,利用这些技术,代码能以最快的速度编译完毕;

.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

多个静态类可以定义相同的扩展方法,如果编译器检测到存在两个或多个扩展方法,就会提示调用不明确,此时需要调用静态方法语法的方式来代替实例方法语法用一个扩展方法扩展一个类型时,同时也扩展了派生类,所以不要将Object作为扩展方法的第一个参数,否则这个方法在所有表达式上都能调用扩展方法存在版本控制问题(为同一个类型定义两个相同的扩展方法,后来者会把前面的覆盖掉,导致行为不一致)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有