You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#编译生成IL中IL_0000分配的作用及Func<int32>与DisplayClass的关联

Great questions! Let's start by laying out the code context clearly, then dive into each question one by one.

Original C# Code
static void Main(string[] args) { 
    int val = int.Parse(Console.ReadLine()); 
    Do(() => { 
        if (val == 0) return 1; 
        return 42; 
    }); 
} 
public static int Do(Func<int> query) { 
    return query(); 
}
Generated IL Code for Main
.method private hidebysig static void Main( string[] args ) cil managed { 
    .entrypoint 
    .maxstack 8 
    IL_0000: newobj instance void ConsoleApp1.Program/'<>c__DisplayClass0_0'::.ctor() // [30 13 - 30 53] 
    IL_0005: dup 
    IL_0006: call string [System.Console]System.Console::ReadLine() 
    IL_000b: call int32 [System.Runtime]System.Int32::Parse(string) 
    IL_0010: stfld int32 ConsoleApp1.Program/'<>c__DisplayClass0_0'::val // [31 13 - 36 16] 
    IL_0015: ldftn instance int32 ConsoleApp1.Program/'<>c__DisplayClass0_0'::'<Main>b__0'() 
    IL_001b: newobj instance void class [System.Runtime]System.Func`1<int32>::.ctor(object, native int) 
    IL_0020: call int32 ConsoleApp1.Program::Do(class [System.Runtime]System.Func`1<int32>) 
    IL_0025: pop // [39 9 - 39 10] 
    IL_0026: ret 
} // end of method Program::Main
Questions & Answers

1. What's the purpose of the allocation at IL_0000?

That allocation creates an instance of the compiler-generated <>c__DisplayClass0_0 type—this is how C# handles closures. Your lambda expression references the local variable val from the Main method. Since lambdas can potentially outlive the scope of the method where they're defined (even if not in this specific case), the compiler can't keep val on the stack. Instead, it wraps the variable in a class (the "display class") so the lambda can access it as an instance field.

The steps right after this allocation reinforce this:

  • IL_0005: dup keeps a reference to the display class instance on the stack
  • After parsing the input to get val, IL_0010: stfld stores that value into the val field of the display class instance.

2. How is the association between Func<int32> and the DisplayClass established? Is it via IL_0015 and IL_001b?

You're exactly right—those two instructions are what tie everything together:

  • IL_0015: ldftn loads the method address of the compiler-generated <Main>b__0 method. This method is the actual implementation of your lambda (it checks the val field of the display class and returns 1 or 42).
  • IL_001b: newobj creates a new Func<int> instance. The Func<T> constructor takes two parameters:
    1. The target object (the display class instance we created earlier, which is still on the stack from the dup at IL_0005)
    2. The method address we just loaded with ldftn

This binds the Func<int> to both the display class instance (so it can access the val field) and the lambda's implementation method. When Do calls query(), it's invoking that <Main>b__0 method on the display class instance.

内容的提问来源于stack exchange,提问作者Lou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:02:43