考虑以下代码:
class Program
{
static void Main(string[] args)
{
Func<uint> fibN = () => Fibonacci(n);
}
static uint Fibonacci(uint n)
{
return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
}
}
只要没有n
合适类型的变量可以使用,它就不会出现。但是,如果您添加:
uint n = 5;
进入Main
方法或
static uint n = 5;
到类,代码将编译。
让我们拆解。对于以下代码:
static void Main(string[] args)
{
uint n = 3;
Func<uint> fibN = () => Fibonacci(n);
}
我们得到:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 3
.locals init ([0] class [mscorlib]System.Func`1<uint32> fibN,
[1] class Utils.Program/'<>c__DisplayClass1' 'CS$<>8__locals2')
IL_0000: newobj instance void Utils.Program/'<>c__DisplayClass1'::.ctor()
IL_0005: stloc.1
IL_0006: nop
IL_0007: ldloc.1
IL_0008: ldc.i4.3
IL_0009: stfld uint32 Utils.Program/'<>c__DisplayClass1'::n
IL_000e: ldloc.1
IL_000f: ldftn instance uint32 Utils.Program/'<>c__DisplayClass1'::'<Main>b__0'()
IL_0015: newobj instance void class [mscorlib]System.Func`1<uint32>::.ctor(object,
native int)
IL_001a: stloc.0
IL_001b: nop
IL_001c: ret
} // end of method Program::Main
在这段代码中,您可能会发现一个隐藏类c__DisplayClass1
,我们可以在其中看到一个uint32
名为的公共字段n
:
.field public uint32 n
和方法<Main>b__0
:
.method public hidebysig instance uint32
'<Main>b__0'() cil managed
{
.maxstack 1
.locals init ([0] uint32 CS$1$0000)
IL_0000: ldarg.0
IL_0001: ldfld uint32 Utils.Program/'<>c__DisplayClass1'::n
IL_0006: call uint32 Utils.Program::Fibonacci(uint32)
IL_000b: stloc.0
IL_000c: br.s IL_000e
IL_000e: ldloc.0
IL_000f: ret
} // end of method '<>c__DisplayClass1'::'<Main>b__0'
它实际上调用Fibonacci
并传递了n
变量。所以编译器将局部变量提取n
到一个单独的类中;以及将 lambda 提取到此类的方法中。最后看起来你分配c__DisplayClass1.<Main>b__0
给Func<uint> fibN
.