Alex Aparin
Alex Aparin

Reputation: 4522

GetILGenerator method is not supported by MethodBuilder

I am trying to generate generic method via Reflection API. Here is function which I want to create:

public List<T> CreateList<T>()
{
    return new List<T>();
}

Here is program, which should create assembly with DemoType class, which will contain mentioned CreateList method, generated dynamically:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

class GenericMethodBuilder
{
    public static void Main()
    {
        var asmName = new AssemblyName("DemoMethodBuilder1");
        var demoAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

        var demoModule = demoAssembly.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");
        var demoType = demoModule.DefineType("DemoType", TypeAttributes.Public);

        var create_list_method = demoType.DefineMethod("CreateList", MethodAttributes.Public | MethodAttributes.Static);

        var TInput = create_list_method.DefineGenericParameters(new string[] { "TInput" })[0];
        var t_list_type = typeof(List<>).MakeGenericType(TInput);

        create_list_method.SetParameters(Type.EmptyTypes);
        create_list_method.SetReturnType(t_list_type);

        var ilgen = create_list_method.GetILGenerator();

        ilgen.Emit(OpCodes.Newobj, t_list_type.GetConstructors()[0]);
        ilgen.Emit(OpCodes.Ret);

        Type dt = demoType.CreateType();
        demoAssembly.Save(asmName.Name + ".dll");
    }
}

But during execution create_list_method.GetILGenerator() I receive NotSupportedException at with message:

Additional information: Specified method is not supported.

What's wrong with this method? I checked out docs, and it seems like ok.

Upvotes: 0

Views: 119

Answers (1)

thehennyy
thehennyy

Reputation: 4216

The received exception is:

[System.NotSupportedException: Specified method is not supported.] at System.Reflection.Emit.TypeBuilderInstantiation.GetConstructors(BindingFlags bindingAttr) at GenericMethodBuilder.Main() :line 26

at the GetConstructor call.

This happens because you try to get the constructor of a not yet constructable type List<TInput>.

The way to go is to use the magic of the static TypeBuilder.GetConstructor-method to create a appropriate representation of the generics type constructor:

ilgen.Emit(OpCodes.Newobj, TypeBuilder.GetConstructor(t_list_type, typeof(List<>).GetConstructors()[0]));

The msdn entry for TypeBuilder.GetConstructor provides a quite extensive explanation as well as examples.

Upvotes: 1

Related Questions