简体   繁体   English

“方法未在泛型类型定义中声明”错误

[英]“Method is not declared within generic type definition” error

I am trying to generate dynamically method like that: 我试图像这样生成动态方法:

MyList<T> CreateList<T>(T arg) => new MyList<T>(){arg};

Here is modification of program from documentation (original program from https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-define-a-generic-method-with-reflection-emit ). 以下是来自文档的程序修改(原始程序来自https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-define-a-generic-method-with-reflection - 发送 )。 All I want to invoke Add method, defined within base class List . 我只想调用基类List定义的Add方法。 I am getting this method info via TypeBuilder.GetMethod method: 我通过TypeBuilder.GetMethod方法获取此方法信息:

public class MyList<T> : List<T>
{
}
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(MyList<>).MakeGenericType(TInput);

    create_list_method.SetParameters(new Type[] { TInput });
    create_list_method.SetReturnType(t_list_type);

    var ilgen = create_list_method.GetILGenerator();

    ilgen.Emit(OpCodes.Newobj, TypeBuilder.GetConstructor(t_list_type, typeof(MyList<>).GetConstructors()[0]));
    ilgen.Emit(OpCodes.Dup);
    ilgen.Emit(OpCodes.Ldarg_0);
    ilgen.Emit(OpCodes.Callvirt, TypeBuilder.GetMethod(t_list_type, typeof(MyList<>).GetMethod("Add")));
    ilgen.Emit(OpCodes.Ret);

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

Execution of program is failed at ilgen.Emit(OpCodes.Callvirt, TypeBuilder.GetMethod(t_list_type, typeof(MyList<>).GetMethod("Add"))); ilgen.Emit(OpCodes.Callvirt, TypeBuilder.GetMethod(t_list_type, typeof(MyList<>).GetMethod("Add")));执行程序失败ilgen.Emit(OpCodes.Callvirt, TypeBuilder.GetMethod(t_list_type, typeof(MyList<>).GetMethod("Add"))); with message: 有消息:

The specified method cannot be dynamic or global and must be declared on a generic type definition 指定的方法不能是动态的或全局的,必须在泛型类型定义上声明

I cannot understand, why does such code fail? 我无法理解,为什么这样的代码失败了? As for me, I think that it should work - I intentionally used static method TypeBuilder.GetMethod 至于我,我认为它应该工作 - 我故意使用静态方法TypeBuilder.GetMethod

I recommend you to always have a decompiler at hand when trying to create IL. 我建议你在尝试创建IL时总是有一个反编译器 You are nearly there, but the Add method is not definied in MyList but in List as you can see here: 就快成功了,但Add方法不definied MyList但在List ,你可以在这里看到:

IL_0000: newobj instance void class MyList`1<!!T>::.ctor()
IL_0005: dup
IL_0006: ldarg.1
IL_0007: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<!!T>::Add(!0)
IL_000c: ret

So that is what you have to tell the static TypeBuilder method: 这就是你必须告诉静态TypeBuilder方法:

var add = TypeBuilder.GetMethod(typeof(List<>).MakeGenericType(TInput), typeof(List<>).GetMethod("Add"))
ilgen.Emit(OpCodes.Callvirt, add);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM