反射生成和泛型类型

Imp*_*rks 14 c# reflection.emit

我还有另一个令人讨厌的时刻Reflection.Emit和类型管理.

比如,我有一个名为的类型MyType,它在动态生成的程序集中定义.调用MyType.GetMethods()结果NotSupportedException,这减少了我编写自己的包装器和查找表的集合.但是,当我在GetMethods()使用我自己的类型作为泛型参数的标准泛型类型上调用或任何其他内省方法时,也会发生同样的情况:

  • Tuple<int, string> =>工作正常
  • Tuple<int, MyType> =>例外

我可以从泛型类型定义中获取方法列表:

typeof(Tuple<int, MyType).GetGenericTypeDefinition().GetMethods()

但是,这些方法具有通用占位符而不是实际值(例如T1,TResult等等).我不想写另一个将通用参数追溯到其原始值的kludge.

代码示例:

var asmName = new AssemblyName("Test");
var access = AssemblyBuilderAccess.Run;
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, access);
var module = asm.DefineDynamicModule("Test");

var aType = module.DefineType("A");
var tupleType = typeof(Tuple<,>);
var tuple = tupleType.MakeGenericType(new [] { typeof(int), aType });

tuple.GetProperty("Item1"); // <-- here's the error
Run Code Online (Sandbox Code Playgroud)

所以问题是:

  1. 如何检测类型是否可以安全调用GetMethods()以及类似的方法?
  2. 如果类型不安全,如何获取实际的方法列表及其通用参数值?

Imp*_*rks 7

我在后续问题中得到了答案.该TypeBuilder班有一堆静态重载这些方法都完成的事情:

var genericTuple = typeof(Tuple<,>);
var myTuple = genericTuple.MakeGenericType(typeof(int), myType);
var ctor = TypeBuilder.GetConstructor(myTuple, genericTuple.GetConstructors().First());
Run Code Online (Sandbox Code Playgroud)

奇怪的是,没有超载GetProperty.但是,仍然可以使用GetMethod以下方法解析属性getter和setter :

var genericGetter = typeof(Tuple<,>).GetProperty("Item1").GetMethod;
var actual = TypeBuilder.GetMethod(myTuple, genericGetter);
Run Code Online (Sandbox Code Playgroud)