使用 Reflection.Emit 实例化具有泛型参数的泛型类型
Using Reflection.Emit to instantiate Generic Type with Generic Parameters
我的目标是使用反射发射来构造泛型类型,并使用创建的泛型方法的泛型参数
所以创建的泛型方法的最终结果类似于
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);
例外是
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)
,它 return 是 TypeBuilderInstantiation 的一个新实例
类型 TypeBuilderInstantiation 只不过是抽象类型的空实现 'TypeInfo' [这是一个抽象实现。 'Type'] 类型的所有方法抛出不支持的异常
我的目标不是为 return new List 创建一个方法,它比这更复杂,但我的障碍与这样做是一样的。
感谢您的帮助。
是的,这绝对是有窍门的。事实上,您不能在 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);
每当您想在代表 unconstructed/dependent 类型的 Type
实例上调用方法时,请在 Reflection.Emit 层次结构中寻找具有相同名称的方法。
除其他外,这种传入 MethodInfo
通用版本的设计模式允许您区分对重载 Class<T=int>.Foo(T)
和 Class<T=int>.Foo(int)
.
的调用
我的目标是使用反射发射来构造泛型类型,并使用创建的泛型方法的泛型参数 所以创建的泛型方法的最终结果类似于
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);
例外是
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)
,它 return 是 TypeBuilderInstantiation 的一个新实例类型 TypeBuilderInstantiation 只不过是抽象类型的空实现 'TypeInfo' [这是一个抽象实现。 'Type'] 类型的所有方法抛出不支持的异常
我的目标不是为 return new List 创建一个方法,它比这更复杂,但我的障碍与这样做是一样的。
感谢您的帮助。
是的,这绝对是有窍门的。事实上,您不能在 TypeBuilderInstantiation
上调用任何方法。相反,TypeBuilder
会让您获得依赖类型的构造函数。
The
GetConstructor
method provides a way to get aConstructorInfo
object that represents a constructor of a constructed generic type whose generic type definition is represented by aTypeBuilder
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);
每当您想在代表 unconstructed/dependent 类型的 Type
实例上调用方法时,请在 Reflection.Emit 层次结构中寻找具有相同名称的方法。
除其他外,这种传入 MethodInfo
通用版本的设计模式允许您区分对重载 Class<T=int>.Foo(T)
和 Class<T=int>.Foo(int)
.