| 加入收藏| 设为首页| 联系我们
深入理解C# 3.0的新特性(2):Extension Method - Part II
http://www.domcn.org 文章来源:本站收藏 点击数:
四、Extension Method的本质 通过上面一节的介绍,我们知道了在C#中如何去定义一个Extension Method:它是定义在一个Static class中的、第一个Parameter标记为this关键字的Static Method。在这一节中,我们来进一步认识Extension Method。 和C# 3.0的其他新特性相似,Extension Method仅仅是C#这种.NET Programming Language的新特性而已。我们知道,C#是一种典型的编译型的语言,我们编写的Source Code必须先经过和C# Compiler编译成Assembly,才能被CLR加载,被JIT 编译成Machine Instruction并最终被执行。C# 3.0的这些新的特性大都影响Source被C# Compiler编译成Assembly这个阶段,换句话说,这些新特仅仅是Compiler的新特性而已。通过对Compiler进行修正,促使他将C# 3.0引入的新的语法编译成相对应的IL Code,从本质上看,这些IL Code 和原来的IL并没有本质的区别。所有当被编译生成成Assembly被CLR加载、执行的时候,CLR是意识不到这些新的特性的。 从Extension Method的定义我们可看出,Extension Method本质上是一个Static Method。但是我们往往以Instance Method的方式进行调用。C# Compiler的作用很明显:把一个以Instance Method方式调用的Source Code编译成的于对应于传统的Static Method调用的IL Code。 虽然Extension Method本质上仅仅是一个Static Class的Static Method成员,但是毕竟和传统的Static Method有所不同:在第一个Parameter前加了一个this关键字。我们现在来看看他们之间的细微的差异。我们先定义一个一般的Static Method: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public static Vector Adds(Vector v, Vector v1){ return new Vector { X = v.X + v1.X, Y = v.Y + v1.Y };} 注:Vector的定义参见《深入理解C# 3.0的新特性(2):Extension Method - Part I》。 我们来看看通过Compiler进行编译生成的IL: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->.method private hidebysig static void Main(string[] args) cil managed{ .entrypoint // Code size 50 (0x32) .maxstack 2 .locals init ([0] class Artech.ExtensionMethod.Vector v, [1] class Artech.ExtensionMethod.Vector <>g__initLocal0) IL_0000: nop IL_0001: newobj instance void Artech.ExtensionMethod.Vector::.ctor() IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: ldc.r8 1. IL_0011: callvirt instance void Artech.ExtensionMethod.Vector::set_X(float64) IL_0016: nop IL_0017: ldloc.1 IL_0018: ldc.r8 2. IL_0021: callvirt instance void Artech.ExtensionMethod.Vector::set_Y(float64) IL_0026: nop IL_0027: ldloc.1 IL_0028: stloc.0 IL_0029: ldloc.0 IL_002a: ldloc.0 IL_002b: call class Artech.ExtensionMethod.Vector Artech.ExtensionMethod.Extension::Adds(class Artech.ExtensionMethod.Vector,class Artech.ExtensionMethod.Vector) IL_0030: stloc.0 IL_0031: ret} // end of method Program::Main 对了解IL的人来说,对上面的IL code应该很容易理解。 我们再来看看对于通过下面的方式定义的Extension Method: public static class Extension { public static Vector Adds(this Vector v, Vector v1) { return new Vector { X = v.X + v1.X, Y = v.Y + v1.Y }; }} 对于得IL如下: .method public hidebysig static class Artech.ExtensionMethod.Vector Adds(class Artech.ExtensionMethod.Vector v,class Artech.ExtensionMethod.Vector v1) cil managed{ .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) // Code size 53 (0x35) .maxstack 3 .locals init ([0] class Artech.ExtensionMethod.Vector <>g__initLocal0, [1] class Artech.ExtensionMethod.Vector CS$1$0000) IL_0000: nop IL_0001: newobj instance void Artech.ExtensionMethod.Vector::.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldarg.0 IL_0009: callvirt instance float64 Artech.ExtensionMethod.Vector::get_X() IL_000e: ldarg.1 IL_000f: callvirt&
四、Extension Method的本质
通过上面一节的介绍,我们知道了在C#中如何去定义一个Extension Method:它是定义在一个Static class中的、第一个Parameter标记为this关键字的Static Method。在这一节中,我们来进一步认识Extension Method。
和C# 3.0的其他新特性相似,Extension Method仅仅是C#这种.NET Programming Language的新特性而已。我们知道,C#是一种典型的编译型的语言,我们编写的Source Code必须先经过和C# Compiler编译成Assembly,才能被CLR加载,被JIT 编译成Machine Instruction并最终被执行。C# 3.0的这些新的特性大都影响Source被C# Compiler编译成Assembly这个阶段,换句话说,这些新特仅仅是Compiler的新特性而已。通过对Compiler进行修正,促使他将C# 3.0引入的新的语法编译成相对应的IL Code,从本质上看,这些IL Code 和原来的IL并没有本质的区别。所有当被编译生成成Assembly被CLR加载、执行的时候,CLR是意识不到这些新的特性的。
从Extension Method的定义我们可看出,Extension Method本质上是一个Static Method。但是我们往往以Instance Method的方式进行调用。C# Compiler的作用很明显:把一个以Instance Method方式调用的Source Code编译成的于对应于传统的Static Method调用的IL Code。
虽然Extension Method本质上仅仅是一个Static Class的Static Method成员,但是毕竟和传统的Static Method有所不同:在第一个Parameter前加了一个this关键字。我们现在来看看他们之间的细微的差异。我们先定义一个一般的Static Method:
注:Vector的定义参见《深入理解C# 3.0的新特性(2):Extension Method - Part I》。
我们来看看通过Compiler进行编译生成的IL:
对了解IL的人来说,对上面的IL code应该很容易理解。
我们再来看看对于通过下面的方式定义的Extension Method:
对于得IL如下:
[1] [2] [3] [4] [5] [6] [7] [8] [9] 下一页