Метод GetILGenerator не поддерживается MethodBuilder - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь сгенерировать универсальный метод через Reflection API.Вот функция, которую я хочу создать:

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

Вот программа, которая должна создать сборку с классом DemoType, который будет содержать упомянутый метод CreateList, сгенерированный динамически:

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

Но во время выполнения create_list_method.GetILGenerator() Я получаю NotSupportedException в с сообщением:

Дополнительная информация: указанный метод не поддерживается.

Что не так с этим методом?Я проверил документы, и кажется, что все в порядке.

1 Ответ

0 голосов
/ 04 июня 2018

Получено исключение:

[System.NotSupportedException: указанный метод не поддерживается.] В System.Reflection.Emit.TypeBuilderInstantiation.GetConstructors (BindingFlags bindingAttr) в GenericMethodBuilder.Main ():строка 26

при вызове GetConstructor.

Это происходит потому, что вы пытаетесь получить конструктор еще не конструируемого типа List<TInput>.

можно использовать магию статического TypeBuilder.GetConstructor -метода для создания соответствующего представления конструктора обобщенных типов:

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

Запись msdn для TypeBuilder.GetConstructor предоставляет довольно подробное объяснение, а также примеры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...