2015-12-13 10 views
-2

Я хочу знать, как генерировать следующий метод: myMethod с ilGenerator.Как вызвать метод в поле с ILGenerator.Emit?

public class MyClass { 
    private MyField myField; 

    public int myMethod(int b) { 
      return myField.someMethod(b); 
    } 
} 

Может кто-нибудь мне помочь?

+1

Что вы пробовали? Как это случилось? Вы рассматривали метод в ildasm и пытались его воспроизвести? – svick

ответ

0
class Program 
{ 
    static MethodAttributes attrs = MethodAttributes.Public | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig; 

    static Type CreateType() { 
     var myDomain = Thread.GetDomain(); 
     var myAsmName = new AssemblyName { Name = "Demo" }; 
     var myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); 
     var moudle = myAsmBuilder.DefineDynamicModule("DemoModule", "Demo.dll"); 
     var typeBuilder = moudle.DefineType("MyClass", TypeAttributes.Public | TypeAttributes.BeforeFieldInit); 
     var fieldBuilder = typeBuilder.DefineField("myField", typeof(MyField), FieldAttributes.Private); 
     var ctorBuilder = typeBuilder.DefineConstructor(attrs, CallingConventions.HasThis | CallingConventions.Standard, Type.EmptyTypes); 
     var methodBuilder = typeBuilder.DefineMethod("MyMethod", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(int), new[] { typeof(int) }); 
     var ctorILGen = ctorBuilder.GetILGenerator(); 
     var ilGen = methodBuilder.GetILGenerator(); 
     var someMethod = fieldBuilder.FieldType.GetMethod("SomeMethod"); 

     ctorILGen.Emit(OpCodes.Ldarg_0); 
     ctorILGen.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); 
     ctorILGen.Emit(OpCodes.Ldarg_0); 
     ctorILGen.Emit(OpCodes.Newobj, fieldBuilder.FieldType.GetConstructor(Type.EmptyTypes)); 
     ctorILGen.Emit(OpCodes.Stfld, fieldBuilder); 
     ctorILGen.Emit(OpCodes.Ret); 

     ilGen.Emit(OpCodes.Ldarg_0); 
     ilGen.Emit(OpCodes.Ldfld, fieldBuilder); 
     ilGen.Emit(OpCodes.Ldarg_1); 
     ilGen.Emit(OpCodes.Callvirt, someMethod); 
     ilGen.Emit(OpCodes.Ret); 

     return typeBuilder.CreateType(); 
    } 

    static void Main(string[] args) { 
     var type = CreateType(); 
     dynamic instance = Activator.CreateInstance(type); 

     Console.WriteLine(instance.MyMethod(10)); 
    } 
} 

сгенерирует

public class MyClass 
{ 
    private MyField myField; 

    public MyClass() { 
     myField = new MyField(); 
    } 

    public int myMethod(int b) { 
     return myField.SomeMethod(b); 
    } 

} 
public class MyField 
{ 
    public int SomeMethod(int i) { 
     return i; 
    } 
}