技术开发 频道

C#与.NET闭包对比示例解析

  这两个返回的匿名函数的唯一区别就是返回的委托中变量n的作用域不一样而已,T1中变量n是属于T1的,而在T4中,n则是属于匿名函数本身的。但我们看看IL代码就会发现这里面的大不同了:

.method public hidebysig instance class [mscorlib]System.Func`1<int32> T1() cil managed{
.maxstack
3
.locals init (
[0] class ConsoleApplication1.TCloser/<>c__DisplayClass1 CS$<>8__locals2,
[1] class [mscorlib]System.Func`1<int32> CS$1$0000)
L_0000: newobj instance void ConsoleApplication1.TCloser/<>c__DisplayClass1::.ctor()
L_0005: stloc
.0
L_0006: nop
L_0007: ldloc
.0
L_0008: ldc.i4.s
10
L_000a: stfld int32 ConsoleApplication1.TCloser/<>c__DisplayClass1::n
L_000f: ldloc
.0
L_0010: ldftn instance int32 ConsoleApplication1.TCloser/<>c__DisplayClass1::<T1>b__0()
L_0016: newobj instance void
[mscorlib]System.Func`1<int32>::.ctor(object, native int)
L_001b: stloc
.1
L_001c: br.s L_001e
L_001e: ldloc
.1
L_001f: ret
}
.method public hidebysig instance class
[mscorlib]System.Func`1<int32> T4() cil managed
{
.maxstack
3
.locals init (
[0] class [mscorlib]System.Func`1<int32> CS$1$0000)
L_0000: nop
L_0001: ldsfld class
[mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
L_0006: brtrue.s L_001b
L_0008: ldnull
L_0009: ldftn int32 ConsoleApplication1.TCloser::<T4>b__3()
L_000f: newobj instance void
[mscorlib]System.Func`1<int32>::.ctor(object, native int)
L_0014: stsfld class
[mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
L_0019: br.s L_001b
L_001b: ldsfld class
[mscorlib]System.Func`1<int32> ConsoleApplication1.TCloser::CS$<>9__CachedAnonymousMethodDelegate4
L_0020: stloc
.0
L_0021: br.s L_0023
L_0023: ldloc
.0
L_0024: ret
}

  看IL代码你就会很容易发现其中究竟了,在T1中,函数对返回的匿名委托构造的是一个类,名称为newobj instance void ConsoleApplication1.TCloser/<>c__DisplayClass1::.ctor(),而在T4中,则是仍然是一个普通的Func委托,只不过级别变为类级别了而已。

  那我们接着看看T1中声明的类c__DisplayClass1是何方神圣:

.class auto ansi sealed nested private beforefieldinit <>c__DisplayClass1
extends [mscorlib]System.Object{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed{}
.method public hidebysig instance int32
<T1>b__0() cil managed{}
.field public int32 n
}
2
相关文章