.class public auto ansi abstract sealed beforefieldinit TestExtension.StringExtension
extends [System.Runtime]System.Object
{
.custom instance void
[System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute
::.ctor() = (
01 00 00 00
)
// Methods
.method public hidebysig static
int32 ToInt32 (
string str
) cil managed
{
.custom instance void
[System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute
::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2050
// Code size 31 (0x1f)
.maxstack 2
.locals init (
[0] int32,
[1] bool,
[2] int32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldloca.s 0
IL_0004: call bool [System.Runtime]System.Int32::TryParse(string, int32&)
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: brfalse.s IL_0012
IL_000d: nop
IL_000e: ldloc.0
IL_000f: stloc.2
IL_0010: br.s IL_001d
IL_0012: ldstr "无法转换为Int32类型"
IL_0017: newobj instance void [System.Runtime]System.ArgumentException::.ctor(string)
IL_001c: throw
IL_001d: ldloc.2
IL_001e: ret
} // end of method StringExtension::ToInt32
} // end of class TestExtension.StringExtension
我们看一下调用后的效果,和直接调用静态方法一样TestExtension.StringExtension::ToInt32(string) ,至此,我们已经知道了扩展方法的使用了,编译器绑定,底层调用和静态调用一直,这也解释了一个问题,就是当类型为空的时候,为什么调用扩展方法了
.namespace Test
{
.class private auto ansi beforefieldinit Test.Program
extends [System.Runtime]System.Object
{
// Methods
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x207b
// Code size 24 (0x18)
.maxstack 8
.entrypoint
IL_0000: nop
IL_0001: ldstr "2"
IL_0006: call int32 TestExtension.StringExtension::ToInt32(string)
IL_000b: call void [System.Console]System.Console::WriteLine(int32)
IL_0010: nop
IL_0011: call string [System.Console]System.Console::ReadLine()
IL_0016: pop
IL_0017: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2094
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Program::.ctor
} // end of class Test.Program
}
4、扩展方法的使用及其注意事项
扩展方法虽然很好用,但是如果我们扩展的对象发生了版本迭代,则会增加扩展方法失效的风险。
一下是在使用扩展方法时需要注意的地方
扩展方法与该类型中定义的方法具有相同的签名,编译器总是绑定到该实例方法,也就是扩展方法永远不会被调用,这也就回答了题目刚开始所说的问题。同时这个地方应该是考虑到了程序安全的问题,不然很容易出现代码注入问题。 当出现命名空间不同时,则需要使用using导入命名空间 同时扩展方法可以被修饰为internal,public,但需要类和扩展方法保持同样的修饰标识









