Reflection.Emit Create Generic Inherited Methods

Firstly, I want to say that this is for a project in college, so I am not looking for a solution, but just help in understanding what I'm doing wrong, so I can try to fix it.

I need to dynamically create a class that inherits another class. Each method is expected to invoke the base method, adding additional code (in this case, to send MethodInfo to the static method, so I can count how many times the method is called).

An example of what I want to do:

public class A
{
   public virtual void M1(B arg0, int arg1)
   { //do stuff
   }
}

And dynamically create this:

public class InstrA : A
{
    public override void M1(B arg0, int arg1)
    {
       base.M1(arg0,arg1)
       ProfilerCounter.LogMethod(typeof(InstrA).GetMethod("M1"));
    }
}

I can do this, except in cases where there are common methods ... I searched all over the Internet, read MSND How To: Define a general method, etc., but to no avail.

My code for creating the method is as follows: (Edited)

public static void BuildMethod(MethodInfo method, TypeBuilder dest)
{           
    Type[] param_types = GetParameterTypes(method.GetParameters());
    MethodBuilder mb = dest.DefineMethod(
       method.Name,
       method.Attributes);

    Type toReturn = method.ReturnType;

    mb.SetReturnType(toReturn);
    mb.SetParameters(param_types);        

    //from here I create the IL code, so that it calls base and then adds the methodinfo to a counter
    //so that everytime the method is run, it will register
    var getMethodMethod = typeof(MethodBase).GetMethod(
            "GetMethodFromHandle",
            new[] { typeof(RuntimeMethodHandle) });          

        ILGenerator il_method = mb.GetILGenerator();
        il_method.Emit(OpCodes.Ldarg_0);
        for (int i = 0; i < param_types.Length; i++)
        {
            il_method.Emit(OpCodes.Ldarg, i + 1);
        }
        il_method.Emit(OpCodes.Call, method);
        il_method.Emit(OpCodes.Ldtoken, method);
        il_method.Emit(OpCodes.Call, getMethodMethod);
        il_method.Emit(OpCodes.Castclass, typeof(MethodInfo));           
        il_method.Emit(OpCodes.Call, typeof(ProfilerCounter).GetMethod("LogMethod"));
        il_method.Emit(OpCodes.Ret);

        dest.DefineMethodOverride(mb, method);
}

TypeBuilder.CreateType(), TypeLoadException, , , , .

, .

.

+4
1

, ... , MethodBuilder.DefineGenericParameter(..)

,

MethodBuilder mb = dest.DefineMethod(
   method.Name,
   method.Attributes);

if (method.IsGenericMethod)
{
    Type[] genericTypes = method.GetGenericArguments();
    foreach (Type t in genericTypes)
    {
        mb.DefineGenericParameters(t.Name);
    }
}

mb.SetReturnType(method.ReturnType);
mb.SetParameters(param_types);

, ... builder.

+2

All Articles