IL代码中的C#预处理器指令

Tar*_*nko 0 .net c# .net-assembly .net-core

我尝试在C#中使用简单的预处理程序指令进行调试和发布模式.

例如:

using System;
public class C {
    public void M() {
        #if DEBUG
            Console.WriteLine("Debug");
        #else
            Console.WriteLine("Release");
        #endif
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码非常简单明了.

但是当我看到IL代码时,我没有关于debug指令的任何内容.

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 13 (0xd)
        .maxstack 8

        IL_0000: nop
        IL_0001: ldstr "Release"
        IL_0006: call void [mscorlib]System.Console::WriteLine(string)
        IL_000b: nop
        IL_000c: ret
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x205e
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method C::.ctor

} // end of class C
Run Code Online (Sandbox Code Playgroud)

这对我很有意思,为什么会发生.

我的意思是为什么我在IL代码中没有看到任何有关DEBUG模式的内容?

PS我使用sharplab查看IL代码.

PS2直播示例

Dan*_*ite 6

这是因为编译器使用预处理程序指令根据配置生成不同的IL代码.它不被CLR使用.

至于为什么SharpLab没有做正确的事情,它使用Rosyln并且只设置优化设置.它不设置预处理器变量.

public void SetOptimize([NotNull] IWorkSession session, [NotNull] string optimize) {
    var project = session.Roslyn.Project;
    var options = ((CSharpCompilationOptions)project.CompilationOptions);
    session.Roslyn.Project = project.WithCompilationOptions(
        options.WithOptimizationLevel(optimize == Optimize.Debug ? OptimizationLevel.Debug : OptimizationLevel.Release)
    );
}
Run Code Online (Sandbox Code Playgroud)

我建议你用SharpLab打开一个问题,他们实现了这个按预期工作.