Тот факт, что компилятор C # генерирует локальные переменные, которых нет в исходном коде C #, я думаю, следует ожидать. Это связано с тем, что стек IL не всегда является отличным местом для хранения некоторых временных значений, поскольку вы можете получить доступ только к его вершине.
И это особенно касается отладочных сборок, потому что они оптимизированы для отладки, а не для производительности или использования памяти. Я понятия не имею, как эти местные жители помогают отладчику, или помогают ли они вообще, но я предполагаю, что они действительно имеют свою точку зрения.
В частности, ваш метод на самом деле не будет компилироваться, как указывал jmh_gr, потому что вы не можете неявно привести long
к int
. Если я изменяю тип j
на int
, он выдает код, подобный этому, при использовании конфигурации отладки (декомпилируется с помощью Reflector, с отключенной оптимизацией):
public static int Test1(short i, int j)
{
int CS$1$0000;
int CS$4$0001;
j = i + j;
CS$4$0001 = j;
if (CS$4$0001 != 1)
{
goto Label_0013;
}
j = 2;
goto Label_0019;
Label_0013:
j = 11;
Label_0019:
CS$1$0000 = j;
Label_001D:
return CS$1$0000;
}
Итак, вы видите, у метода на самом деле есть два локальных, и оба используются. При использовании конфигураций выпуска у сгенерированного IL есть только одна локальная переменная, и это выглядит так:
public static int Test1(short i, int j)
{
int CS$0$0000;
j = i + j;
CS$0$0000 = j;
if (CS$0$0000 != 1)
{
goto Label_0010;
}
j = 2;
goto Label_0014;
Label_0010:
j = 11;
Label_0014:
return j;
}
Похоже, что местный не должен быть необходимым, но, возможно, есть веская причина для этого. И, конечно же, для производительности действительно важна компилированная сборка JIT, а не код IL.