Оператор switch C# может компилироваться в инструкцию переключения CIL или если/else's, в зависимости от случаев в заявлении, как указано here. Есть ли способ заставить компилятор всегда генерировать вариант if/else в блоке кода?Как остановить инструкцию оператора C# от генерации инструкции переключателя CIL
ответ
Самый простой способ - использовать if/else в коде. Помимо всего прочего, это дает читателю более четкое представление о том, что именно вам нужно , вместо того чтобы использовать коммутатор.
EDIT: Хорошо, поэтому читаемость не важна для вас - но в основном, если вы хотите, чтобы скомпилированный код изменился, исходный код должен измениться. Вы можете использовать компилятор Mono и изменить его самостоятельно, но я сомневаюсь, что есть способ заставить компилятор Microsoft эффективно игнорировать то, что вы используете оператор switch.
Операторы switch генерируются лексическим анализатором, поэтому читаемость не вызывает беспокойства. Перезапись генератора для создания, если/else's является последней инстанцией :) – user55017
Вы пробовали использовать другой компилятор (т. Е. Mono) или пытались разместить свои классы-нарушители в отдельной сборке и переключиться на другой язык?
Как вы это делаете, компилятор? Я сделал тест с 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?
У меня нет компилятора ATM, но я был бы шокирован, если бы была создана таблица прыжка для 3-х корпусного коммутатора со значениями 1-1000 (так что 1000 записей). Вероятно, что-то ближе к случаю 1: случай 50: – user55017
Так бы я, но я был бы удивлен, если бы компилятор не выбрал оптимальный код и в вашем случае. Обратите внимание, что только мои три случая вызвали выброс 20 IL-инструкций. – erikkallen
Компилятор действительно выбирает оптимальный код для скорости выполнения, я хочу оптимизировать использование памяти. 20 IL-команд по-прежнему занимают гораздо меньше памяти, чем таблица перехода на 50-100 записей. – user55017
Нет, у вас нет контроля над тем, как компилятор C# выдаст инструкции CIL. И даже если бы вы могли, компилятор AOT или JIT мог бы перевести инструкции CIL на инструкции машинного кода, значительно отличающиеся от того, что вы ожидаете из-за оптимизации оптимизатора компилятора.
Зачем вам это нужно? – ilivewithian