C# 在运行时生成对泛型方法的调用
目标:在运行时生成如下方法:C# 在运行时生成对泛型方法的调用,c#,generics,reflection.emit,C#,Generics,Reflection.emit,目标:在运行时生成如下方法: public void InsertOnSubmit(IQueryable q,to),其中T:class,new() { (q如表所示)。InsertOnSubmit(o); } 我目前的代码是: var tb=mb.DefineType(“DatabaseDataRepository”); //定义并实施其他方法等 /*定义InsertOnSubmit方法*/ var insertOnSubmitMethod=tb.DefineMethod(“InsertOn
public void InsertOnSubmit(IQueryable q,to),其中T:class,new()
{
(q如表所示)。InsertOnSubmit(o);
}
我目前的代码是:
var tb=mb.DefineType(“DatabaseDataRepository”);
//定义并实施其他方法等
/*定义InsertOnSubmit方法*/
var insertOnSubmitMethod=tb.DefineMethod(“InsertOnSubmit”,
MethodAttributes.Public | MethodAttributes.hidebysing | MethodAttributes.Virtual|
方法属性(新闻栏);
var genericInput=insertOnSubmitMethod.DefineGenericParameters(“T”)[0];
genericInput.SetGenericParameterAttributes(GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint);
insertOnSubmitMethod.SetParameters(typeof(IQueryable).MakeGenericType(genericInput),genericInput);
insertOnSubmitMethod.SetReturnType(null);
/*实现InsertOnSubmit方法*/
var saveMethodGen=insertOnSubmitMethod.GetILGenerator();
saveMethodGen.Emit(操作码.Ldarg_1);//推送第一个参数(集合)
saveMethodGen.Emit(opcode.Isinst,typeof(Table.MakeGenericType(genericInput));//将第一个参数强制转换为表
saveMethodGen.Emit(操作码.Ldarg_2);//第二个参数(元素)
saveMethodGen.Emit(opcode.Callvirt,typeof(Table).GetMethod(“InsertOnSubmit”);//在表中插入第二个参数
saveMethodGen.Emit(操作码.Ret);//从InsertOnSubmit方法返回
但在生成的实例上运行此方法会得到:
试图加载格式不正确的程序。(HRESULT:0x8007000B的例外)
在DatabaseDataRepository处使用堆栈。InsertOnSubmit[T](IQueryable`1,T)
我怀疑这行saveMethodGen.Emit(OpCodes.Callvirt,typeof(Table.GetMethod)(“InsertOnSubmit”))中有错误代码>-它实际上应该类似于typeof(Table).MakeGenericType(genericInput).GetMethod(“InsertOnSubmit”)
-但这会抛出NotSupportedException
有什么提示可以解决这个问题吗?
谢谢。您必须使用staticSystem.Reflection.Emit.Typebuilder.GetMethod
方法来创建正确键入的MethodInfo
msdn声明:
返回与泛型类型定义的指定方法相对应的指定构造泛型类型的方法
在您的情况下,这将是:
Typebuilder.GetMethod(typeof(Table<>).MakeGenericType(genericInput), typeof(Table<>).GetMethod("InsertOnSubmit"))
Typebuilder.GetMethod(typeof(Table).MakeGenericType(genericInput),typeof(Table).GetMethod(“InsertOnSubmit”))
您尝试在运行时生成一个方法,而不是像您的示例那样创建带有类型参数的方法,这有什么原因吗?我需要在运行时生成接口的实例。根据调用方的不同,生成代码的规则可能(略有)不同-这超出了问题的范围。@AlexanderBortnik我想说它肯定在问题的范围内,因为它可能是“XY”问题的一种表现形式。。。你问的是如何解X,但实际上你想解Y——这在手边的问题中不存在:)听起来像是一个势函数。你可能想重新考虑你的方法。我在一些非常通用的项目中使用了大量的泛型和反射,从来没有按照您的要求去做过。在某些情况下,我想用这种方法添加对logger的调用,在某些情况下则不是,等等。因此,根据调用方的不同,实现可能会有所不同,但无论如何都需要调用“InsertOnSubmit”。我把这些细节排除在问题之外。