В общем, как конвертировать синтаксис ilasm в вызовы Reflection.Emit? - PullRequest
1 голос
/ 13 июня 2010

Я пишу специальный мини-компилятор и часто просматриваю разобранный CIL, чтобы понять, как это сделать.Но часто не очевидно, как перевести разобранный код в вызовы Reflection.Emit.Существует ли справочное руководство или какой-либо другой источник информации для выполнения этого перевода?

Редактировать : да, отображение кодов операций в ILGenerator довольно просто;Я говорю обо всех других вещах, таких как .directives и атрибуты.Например, как вы узнаете, как написать эквивалент Reflection.Emit, например, Dictionary<TKey,TValue>?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

Или как насчет директивы param?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"

Ответы [ 3 ]

4 голосов
/ 16 июня 2010

Я бы использовал для этой цели компонент EmitHelper из BLToolkit . Он предоставляет свободный API, напоминающий код IL, с оболочкой Reflection.Emit. Пример извлечен из связанной статьи:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();
1 голос
/ 11 апреля 2011

Поскольку никто не мог ответить на вопрос, я пришел к выводу, что не существует документации, показывающей связь между синтаксисом ilasm и вызовами Reflection.Emit.

В качестве примечания я обнаружил, что обычно лучше создавать код во время выполнения, используя RunSharp , чем Reflection.Emit. Когда у меня будет время, я попытаюсь выяснить новую версию Cecil .

1 голос
/ 14 июня 2010

Вы просматриваете IL для класса System.Collections.Generic.Dictionary <>. Имя класса «Dictionary» - это строка, которую вы передаете в ModuleBuilder.DefineType ().

Атрибут .param создается в C # версии 4 или VB.NET для параметров, имеющих значение по умолчанию. Вы устанавливаете его с помощью ParameterBuilder, который вы возвращаете из MethodBuilder.DefineParameter (). Используйте метод SetConstant ().

...