簡體   English   中英

“方法未在泛型類型定義中聲明”錯誤

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

我試圖像這樣生成動態方法:

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

以下是來自文檔的程序修改(原始程序來自https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-define-a-generic-method-with-reflection - 發送 )。 我只想調用基類List定義的Add方法。 我通過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");
}

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"))); 有消息:

指定的方法不能是動態的或全局的,必須在泛型類型定義上聲明

我無法理解,為什么這樣的代碼失敗了? 至於我,我認為它應該工作 - 我故意使用靜態方法TypeBuilder.GetMethod

我建議你在嘗試創建IL時總是有一個反編譯器 就快成功了,但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

這就是你必須告訴靜態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