如何使用ILGenerator.Emit在字段上调用方法



我想知道如何用ilGenerator生成以下方法myMethod

public class MyClass {
     private MyField myField;
     public int myMethod(int b) {
          return myField.someMethod(b);
     }
}

有人能帮我吗?

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;
    }
}

相关内容

  • 没有找到相关文章

最新更新