您的位置:首页 > 其它

扩展方法到底做了什么

2010-05-26 18:41 281 查看
扩展方法是.net3.5以后出现的一个比较优雅的写法,昨天讨论中有同学提出这也是通过反射实现的,不过我并不这么认为。

扩展方法的定义必须是静态类的静态方法,对一个静态类的静态方法进行反射明显不明智。而且linq to object中大量使用扩展方法,如果是用发射实现方法调用,明显过于笨拙。

那么事实到底如何

先定义一个扩展方法和一个同样功能的非扩展方法

IL代码

IL_0000: nop
IL_0001: ldstr "hello world!"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.5
IL_0009: ldstr "..."
IL_000e: call string [StringHelp]StringHelp.StringHelp::CutStr(string,
int32,
string)
IL_0013: call void [mscorlib]System.Console::WriteLine(string)
IL_0018: nop
IL_0019: ldloc.0
IL_001a: ldc.i4.5
IL_001b: ldstr "..."
IL_0020: call string [StringHelp]StringHelp.StringHelp::CutStrNew(string,
int32,
string)
IL_0025: call void [mscorlib]System.Console::WriteLine(string)
IL_002a: nop
IL_002b: ldtoken [StringHelp]StringHelp.StringHelp
IL_0030: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0035: ldstr "CutStr"
IL_003a: call instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Type::GetMethod(string)
IL_003f: ldnull
IL_0040: ldc.i4.3
IL_0041: newarr [mscorlib]System.Object
IL_0046: stloc.1
IL_0047: ldloc.1
IL_0048: ldc.i4.0
IL_0049: ldloc.0
IL_004a: stelem.ref
IL_004b: ldloc.1
IL_004c: ldc.i4.1
IL_004d: ldc.i4.5
IL_004e: box [mscorlib]System.Int32
IL_0053: stelem.ref
IL_0054: ldloc.1
IL_0055: ldc.i4.2
IL_0056: ldstr "..."
IL_005b: stelem.ref
IL_005c: ldloc.1
IL_005d: callvirt instance object [mscorlib]System.Reflection.MethodBase::Invoke(object,
object[])
IL_0062: call void [mscorlib]System.Console::WriteLine(object)

三种调用的方式是这样的:

1、string [StringHelp]StringHelp.StringHelp::CutStr(string, int32, string)

2、string [StringHelp]StringHelp.StringHelp::CutStrNew(string,
int32,
string)

3、instance object [mscorlib]System.Reflection.MethodBase::Invoke(object,
object[])

很明显,并没有使用反射,而是编译器的语法糖,使得调用方法更为简便。在编译时期,编译器会对代码作用域范围内可见的所有静态类,且带this 特征参数的方法进行搜索,

然后透明调用符合特征的方法。

那么效率如何呢



1、86 2、84 3、313

效率基本没有,差别,因为其实调用的方式都没有什么区别,而且性能比反射自然要好很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: