Для чего нужны эти коды? - PullRequest
6 голосов
/ 03 июня 2009

Используя отражатель, я получаю следующий вывод:

.method private hidebysig static class myModelTestarea.Foo Method() cil managed
{
  .maxstack 1
  .locals init ([0] class myModelTestarea.Foo CS$1$0000)
  L_0000: nop 
  L_0001: ldc.i4.0 
  L_0002: newarr object
  L_0007: call object myModelTestarea.Program::Resolve(object[])
  L_000c: castclass myModelTestarea.Foo
  L_0011: stloc.0 
  L_0012: br.s L_0014
  L_0014: ldloc.0 
  L_0015: ret 
}

для

private static Foo Method()
{
  return (Foo)Resolve();
}

private static object Resolve( params object[] args )
{
  return new Foo();
}

Что делают строки 11-14? Я вызываю функцию и получаю результат (строка 7). Я приведу результат к правильному типу повторения (строка c) - почему бы не вернуться прямо сейчас?

Каким-то образом приведенный результат сохраняется как локальная переменная - тогда происходит некодический переход на следующую строку, где локальная переменная загружается снова. Почему?

На мой взгляд, строка 11-14 и локальная переменная могут быть опущены ...?

Ответы [ 2 ]

13 голосов
/ 03 июня 2009

Это похоже на сборку DEBUG, которая оставляет дополнительный IL для помощи отладчику. Попробуйте снова в RELEASE, и он должен выглядеть чище, с оптимизацией и т. Д.

.method private hidebysig static class program/Foo Method() cil managed
{
    .maxstack 8
    L_0000: ldc.i4.0 
    L_0001: newarr object
    L_0006: call object program::Resolve(object[])
    L_000b: castclass program/Foo
    L_0010: ret 
}
4 голосов
/ 03 июня 2009

Это отладочная сборка? Возможно, это ради отладчика.

Я видел подобные вещи в других местах - хотя это почти всегда безопасно. Не забывайте, что большая часть оптимизации выполняется JIT, который может достаточно легко заметить подобные вещи. Единственным недостатком является то, что больше IL намекает на JIT, что метод не должен быть встроен.

...