2010-08-23 1 views
7

Я создаю объект во время выполнения с использованием отражения. Я успешно создал поля, свойства и методы набора. Теперь я хочу добавить метод. Для простоты предположим, что метод просто возвращает случайное число. Как определить тело метода?Как создать метод во время выполнения с помощью Reflection.emit

EDIT:

Да, я смотрел на документацию MSDN вместе с другими ссылками и я начинаю, чтобы моя голова обернута вокруг этого материала. Я вижу, как вышеприведенный пример добавляет и/или многопользовательский, но что, если мой метод делает другие вещи. Как определить, что «материал» Предположим, что я динамически генерировал класс ниже, как бы я создал тело метода GetDetails()?

class TestClass 
{ 
    public string Name { get; set; } 
    public int Size { get; set; } 

    public TestClass() 
    { 
    } 

    public TestClass(string Name, int Size) 
    { 
     this.Name = Name; 
     this.Size = Size; 
    } 

    public string GetDetails() 
    { 
     string Details = "Name = " + this.Name + ", Size = " + this.Size.ToString(); 
     return Details; 
    } 
} 

ответ

15

Для определения методов используется метод MethodBuilder. Чтобы определить тело метода, вы вызываете GetILGenerator(), чтобы получить ILGenerator, а затем вызовите методы Emit, чтобы испустить отдельные инструкции IL. Существует пример по документации MSDN для MethodBuilder, и вы можете найти другие примеры того, как использовать отражение испускает на Using Reflection Emit страницы:

public static void AddMethodDynamically(TypeBuilder myTypeBld, 
            string mthdName, 
            Type[] mthdParams, 
            Type returnType, 
            string mthdAction) 
{ 
    MethodBuilder myMthdBld = myTypeBld.DefineMethod(
              mthdName, 
              MethodAttributes.Public | 
              MethodAttributes.Static, 
              returnType, 
              mthdParams); 
    ILGenerator ILout = myMthdBld.GetILGenerator(); 
    int numParams = mthdParams.Length; 
    for (byte x = 0; x < numParams; x++) 
    { 
     ILout.Emit(OpCodes.Ldarg_S, x); 
    } 
    if (numParams > 1) 
    { 
     for (int y = 0; y < (numParams - 1); y++) 
     { 
      switch (mthdAction) 
      { 
       case "A": ILout.Emit(OpCodes.Add); 
        break; 
       case "M": ILout.Emit(OpCodes.Mul); 
        break; 
       default: ILout.Emit(OpCodes.Add); 
        break; 
      } 
     } 
    } 
    ILout.Emit(OpCodes.Ret); 
} 

Похоже, что вы ищете ресурсы на написание MSIL , Одним из важных ресурсов является класс OpCodes, который имеет член для каждой команды IL. Документация описывает, как работает каждая инструкция. Другим важным ресурсом является либо Ildasm, либо Reflector. Они позволят вам увидеть IL для скомпилированного кода, который поможет вам понять, какой IL вы хотите написать. Запуск GetDetailsMethod через отражатель и выбор языка для выходов IL:

.method public hidebysig instance string GetDetails() cil managed 
{ 
    .maxstack 4 
    .locals init (
     [0] string Details, 
     [1] string CS$1$0000, 
     [2] int32 CS$0$0001) 
    L_0000: nop 
    L_0001: ldstr "Name = " 
    L_0006: ldarg.0 
    L_0007: call instance string ConsoleApplication1.TestClass::get_Name() 
    L_000c: ldstr ", Size = " 
    L_0011: ldarg.0 
    L_0012: call instance int32 ConsoleApplication1.TestClass::get_Size() 
    L_0017: stloc.2 
    L_0018: ldloca.s CS$0$0001 
    L_001a: call instance string [mscorlib]System.Int32::ToString() 
    L_001f: call string [mscorlib]System.String::Concat(string, string, string, string) 
    L_0024: stloc.0 
    L_0025: ldloc.0 
    L_0026: stloc.1 
    L_0027: br.s L_0029 
    L_0029: ldloc.1 
    L_002a: ret 
} 

Чтобы сгенерировать метод, как, динамически, вам нужно будет позвонить ILGenerator.Emit для каждой команды:

ilGen.Emit(OpCodes.Nop); 
ilGen.Emit(OpCodes.Ldstr, "Name = "); 
ilGen.Emit(OpCodes.Ldarg_0); 
ilGen.Emit(OpCodes.Call, nameProperty.GetGetMethod()); 
// etc.. 

Вы можете также хочу искать интродукции в MSIL, например, этот: Introduction to IL Assembly Language.

 Смежные вопросы

  • Нет связанных вопросов^_^