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). All I want to invoke Add
method, defined within base class List
. I am getting this method info via TypeBuilder.GetMethod
method:
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")));
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
Aucun commentaire:
Enregistrer un commentaire