如果我有这样的方法
void SomeMethod () {
Func<A,B> f = a => /*Some code*/;
...
b = f (a);
}
每次调用f
时,是否都会SomeMethod
创建?我的意思是,该行是否需要时间来计算,或者编译器在编译时将某个函数存储在执行时跳过它?
答案 0 :(得分:5)
考虑这个简单的例子:
static void Main(string[] args)
{
Test();
Test();
}
static void Test()
{
Func<int, int> f = a => a * a;
int b = f(2);
Console.WriteLine(b);
}
创建的方法是:
<Test>b__0
的IL代码:
.method private hidebysig static int32 '<Test>b__0'(int32 a) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 2
.locals init ([0] int32 CS$1$0000)
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: mul
IL_0003: stloc.0
IL_0004: br.s IL_0006
IL_0006: ldloc.0
IL_0007: ret
} // end of method Program::'<Test>b__0'
Test
方法的IL代码:
.method private hidebysig static void Test() cil managed
{
// Code size 49 (0x31)
.maxstack 2
.locals init ([0] class [mscorlib]System.Func`2<int32,int32> f,
[1] int32 b)
IL_0000: nop
IL_0001: ldsfld class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0006: brtrue.s IL_001b
IL_0008: ldnull
IL_0009: ldftn int32 ConsoleApplication10.Program::'<Test>b__0'(int32)
IL_000f: newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,
native int)
IL_0014: stsfld class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0019: br.s IL_001b
IL_001b: ldsfld class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0020: stloc.0
IL_0021: ldloc.0
IL_0022: ldc.i4.2
IL_0023: callvirt instance !1 class [mscorlib]System.Func`2<int32,int32>::Invoke(!0)
IL_0028: stloc.1
IL_0029: ldloc.1
IL_002a: call void [mscorlib]System.Console::WriteLine(int32)
IL_002f: nop
IL_0030: ret
} // end of method Program::Test
每次调用Test
方法时,都会加载缓存的匿名委托(Func<int,int>
),然后调用Invoke
方法。
所以答案是,匿名方法(<Test>b__0
)只由编译器创建一次,每次调用函数时都不会创建它。
答案 1 :(得分:4)
C#编译器从lambda箭头创建一个普通(非匿名)方法,然后委托f
将生成&#34;生成&#34;调用列表上的方法。
每次SomeMethod
运行时,都会创建一个Func<,>
委托的新实例,它引用普通(但生成的)方法。
就像:
void SomeMethod () {
Func<A, B> f = StrangeName;
...
b = f(a);
}
static B StrangeName(A a) {
/*Some code*/
}