Generic dynamic method using DefineMethod

This example illustrates how you can define a generic dynamic method and call it. In the sample below we define a method void HelloWorld<T>(T val) in type Hello and call it.

 

The body of the HelloWorld Method accesses the parameter passed to the method and prints it by calling WriteLine. I have created a module so that you can see the IL that is generated from this code.

using System;

using System.Collections.Generic;

using System.Text;

using System.Reflection.Emit;

using System.Reflection;

public interface IHelloWorld {

    void HelloWorld<T>(T val);

}

public class HelloClass {

    static void Main(string[] args) {

     AppDomain cd = System.Threading.Thread.GetDomain();

        AssemblyName an = new AssemblyName();

        an.Name = "HelloClass";

        AssemblyBuilder ab = cd.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);

        ModuleBuilder mb = ab.DefineDynamicModule("HelloModule", "HelloModule.dll", true);

        TypeBuilder tb = mb.DefineType("Hello", TypeAttributes.Class | TypeAttributes.Public);

        TypeBuilder ntb = tb.DefineNestedType("NestedHello",TypeAttributes.NestedPublic, typeof(HelloClass), new Type[] {typeof(IHelloWorld)});

        ntb.AddInterfaceImplementation(typeof(IHelloWorld));

        MethodBuilder meth = ntb.DefineMethod("HelloWorld", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes);

        string[] typeParamNames = {"T"};

        GenericTypeParameterBuilder[] typeParameters = meth.DefineGenericParameters(typeParamNames);

        Type[] parms = { typeParameters[0] };

        meth.SetParameters(parms);

        ILGenerator il = meth.GetILGenerator();

        MethodInfo infoMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });

        if (infoMethod != null)

        {

            il.Emit(OpCodes.Ldarg_1);

            il.Emit(OpCodes.Box, typeParameters[0]);

            il.Emit(OpCodes.Call, infoMethod);

        }

        il.Emit(OpCodes.Ret);

        MethodInfo myHelloMethodInfo = typeof(IHelloWorld).GetMethod("HelloWorld");

        ntb.DefineMethodOverride(meth, myHelloMethodInfo);

        Type myType = tb.CreateType();

        Type myNestedClassType = ntb.CreateType();

        IHelloWorld ihw = (IHelloWorld)Activator.CreateInstance(myNestedClassType);

        ihw.HelloWorld("Calling generic dynamic method");

        ab.Save("Hello.dll");

        return;

    }

}