Reflection.Emit - доступ к верхнему, но одному элементу из стека - PullRequest
9 голосов
/ 05 апреля 2009

Есть ли способ в .NET, использующий Reflection.Emit, получить доступ к самому верхнему элементу из стека? Так что, если A является верхним, а B следующим - я хочу обработать B, тогда A. Было бы хорошо продублировать B выше A (поскольку я могу просто «выдвинуть» второй B, когда доберусь до него) .

В настоящее время я объявляю местный:

    LocalBuilder loc = il.DeclareLocal(typeof(Foo));
    il.Emit(OpCodes.Stloc, loc); // store and pop topmost stack item
    // work with (pop) previous stack item 
    il.Emit(OpCodes.Ldloc, loc); // push old topmost stack item

Есть ли маршрут, который не нуждается в явном локальном?

Ответы [ 4 ]

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

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

1 голос
/ 25 ноября 2009

Я столкнулся с этой же проблемой. Я хотел создать довольно большой метод, и я часто хотел «поменять», чтобы сохранить вычисленное значение. Я был недоволен большим количеством местных жителей, обнаруживающихся в ildasm, и заметил, что BeginScope / EndScope не помогли. Я создал локальный «своп» для контекста моего метода и использовал его для каждой операции свопинга. Это делает сгенерированный IL чище; не уверен, оказывает ли это какое-либо значимое влияние на производительность.

1 голос
/ 05 апреля 2009

В соответствии с тем, что сказал kvb, вы можете попробовать небольшую функцию для некоторого изменения порядка. Не уверен, что это будет быстрее.

1 голос
/ 05 апреля 2009

+ 1 для ответа kvbs, см .: http://www.codeproject.com/KB/msil/msilenhancement.aspx

...