gpt4 book ai didi

c# - 使用 Reflection.Emit 实例化具有泛型参数的泛型类型

转载 作者:太空狗 更新时间:2023-10-30 00:30:14 25 4
gpt4 key购买 nike

我的目标是使用反射发射来构造泛型类型,并带有创建的泛型方法的泛型参数所以创建的通用方法的最终结果类似于

void DoSomeThing<T>(T arg){ 
var list=new List<T>();
}

所以我需要的是用于发出这段代码的代码

    new List<T>

这是我的尝试

        var _assemblyName = "asm.dll";
var _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(_assemblyName), System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);
// ApplyReflectionPermission(asm);

var _moduleBuilder = _assemblyBuilder.DefineDynamicModule("module", _assemblyName, true);


var type = _moduleBuilder.DefineType("type");

var method = type.DefineMethod("DoSomeThing", MethodAttributes.Public | MethodAttributes.Static);
var genericPrms = method.DefineGenericParameters("T");
method.SetParameters(genericPrms);
method.SetReturnType(typeof(void));


var il = method.GetILGenerator();
var listType = typeof(List<>);
var list_of_T = listType.MakeGenericType(genericPrms);


il.DeclareLocal(list_of_T);
var c = list_of_T.GetConstructor(new Type[0]);


il.Emit(OpCodes.Newobj, c);
il.Emit(OpCodes.Stloc, 0);
il.Emit(OpCodes.Ret);
type.CreateType();
_assemblyBuilder.Save(_assemblyName);

异常在这行代码

var c = list_of_T.GetConstructor(new Type[0]);

而且是这行代码造成的

var list_of_T = listType.MakeGenericType(genericPrms);

异常(exception)是

System.NotSupportedException: Specified method is not supported.
at System.Reflection.Emit.TypeBuilderInstantiation.GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetConstructor(Type[] types)

并且通过挖掘 (MakeGenericType) 方法,如果任何参数类型不是 (RuntimeType),它会返回一个新的 TypeBuilderInstantiation 实例

类型 TypeBuilderInstantiation 只不过是抽象类型“TypeInfo”的空实现 [whis is an abstract impl. 'Type'] 类型的所有方法都抛出不支持的异常

我的目标不是创建一个返回新列表的方法,它比这更复杂,但我的障碍与这样做是一样的。

感谢您的帮助。

最佳答案

是的,这肯定有诀窍。事实上,您不能在 TypeBuilderInstantiation 上调用任何方法。 .相反,TypeBuilder将使您获得依赖类型的构造函数。

The GetConstructor method provides a way to get a ConstructorInfo object that represents a constructor of a constructed generic type whose generic type definition is represented by a TypeBuilder object.

https://msdn.microsoft.com/en-us/library/ms145822(v=vs.110).aspx

您首先需要通用的 ConstructorInfo , 来自 typeof(List<>)以通常的方式...

var listDefaultConstructor = listType.GetConstructor(new Type[0]);

然后将其实例化为您的特定通用实现:

var c = TypeBuilder.GetConstructor(list_of_T, listDefaultConstructor);

每当您想在 Type 的实例上调用方法时表示未构造/依赖类型,而是在 Reflection.Emit 层次结构中查找具有相同名称的方法。


除其他事项外,这种传递 MethodInfo 的通用版本的设计模式允许您区分对重载 Class<T=int>.Foo(T) 的调用和 Class<T=int>.Foo(int) .

关于c# - 使用 Reflection.Emit 实例化具有泛型参数的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40220850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com