Как остановить оператор переключения C # от генерации инструкции переключения CIL - PullRequest
4 голосов
/ 18 апреля 2009

Оператор switch в C # может компилироваться в инструкцию переключения CIL или if / else в зависимости от случаев в операторе, как указано здесь . Есть ли способ заставить компилятор всегда генерировать вариант if / else в блоке кода?

Ответы [ 4 ]

7 голосов
/ 18 апреля 2009

Самый простой способ - использовать if / else в вашем коде. Помимо всего прочего, для читателя становится понятнее, что именно это вы хотите, чтобы произошло вместо использования переключателя.

РЕДАКТИРОВАТЬ: Хорошо, поэтому читаемость не важна для вас - но в основном, если вы хотите, чтобы скомпилированный код изменился, исходный код придется изменить. Вы можете использовать Mono-компилятор и модифицировать его самостоятельно, но я сомневаюсь, что есть какой-либо способ заставить компилятор Microsoft эффективно игнорировать использование оператора switch.

2 голосов
/ 18 апреля 2009

Вы пытались использовать другой компилятор (например, Mono) или пытались поместить свои оскорбительные классы в отдельную сборку и переключиться на другой язык для этого?

0 голосов
/ 07 июня 2010

Нет, вы не можете контролировать, как компилятор C # будет генерировать инструкции CIL. И даже если бы вы могли, компилятор AOT или JIT мог бы преобразовать инструкции CIL в инструкции машинного кода, значительно отличающиеся от ожидаемых из-за предварительной оптимизации компилятора.

0 голосов
/ 18 апреля 2009

Как вы заставляете компилятор делать это? Я сделал тест с 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?

...