考慮下面的代碼:
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);
}
}
它不comile,只要有合適的類型的無可變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
。
您必須在範圍內有一些變量'n',其中放置了'fibN'聲明 – horgh 2013-02-12 06:46:53
您可能在該方法的範圍內有一個靜態無符號整數。 – Igoy 2013-02-12 06:54:26