如何阻止C#的switch语句生成CIL开关指令

时间:2009-04-18 10:28:08

标签: c# clr switch-statement

C#的switch语句可以编译为CIL开关指令,或if / else,这取决于所提到的语句here中的情况。有没有办法强制编译器始终在代码块中生成if / else变量?

4 个答案:

答案 0 :(得分:7)

最简单的方法是在代码中使用if / else。除了其他任何东西之外,这使得读者更清楚地知道这是你想要的而不是使用开关。

编辑:好的,所以可读性对你来说并不重要 - 但基本上如果你想要编译代码改变,源代码将不得不改变。您可以使用Mono编译器并自行修改它,但我怀疑是否有任何方法可以让Microsoft编译器有效地忽略您正在使用switch语句。

答案 1 :(得分:2)

您是否尝试过其他编译器(即Mono),或尝试将违规类放在单独的程序集中并切换到不同的语言?

答案 2 :(得分:0)

你是如何让编译器这样做的? 我用VS2008进行了测试:

public static int DoSomething(int i) {
    switch (i) {
        case 1: return 0;
        case 100: return 1;
        case 1000: return 2;
        default: return 3;
    }
}

汇编为:

.method public hidebysig static int32 DoSomething(int32 i) cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 CS$1$0000,
        [1] int32 CS$4$0001)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: stloc.1 
    L_0003: ldloc.1 
    L_0004: ldc.i4.1 
    L_0005: beq.s L_0016
    L_0007: ldloc.1 
    L_0008: ldc.i4.s 100
    L_000a: beq.s L_001a
    L_000c: ldloc.1 
    L_000d: ldc.i4 0x3e8
    L_0012: beq.s L_001e
    L_0014: br.s L_0022
    L_0016: ldc.i4.0 
    L_0017: stloc.0 
    L_0018: br.s L_0026
    L_001a: ldc.i4.1 
    L_001b: stloc.0 
    L_001c: br.s L_0026
    L_001e: ldc.i4.2 
    L_001f: stloc.0 
    L_0020: br.s L_0026
    L_0022: ldc.i4.3 
    L_0023: stloc.0 
    L_0024: br.s L_0026
    L_0026: ldloc.0 
    L_0027: ret 
}

那里没有开关指令。

也许您应该向Microsoft提交错误?

答案 3 :(得分:0)

不,您无法控制C#编译器如何发出CIL指令。即使可以,AOT或JIT编译器也可能将CIL指令转换为本机代码指令,这些指令与先前编译器优化所预期的完全不同。