我与 Reflection.Emit
又经历了一个不愉快的时刻和类型管理。
比如说,我有一个名为 MyType
的类型这是在动态生成的程序集中定义的。
打电话MyType.GetMethods()
结果 NotSupportedException
,这让我不得不编写自己的包装器和查找表集。然而,当我调用 GetMethods()
时,同样的事情发生了。或使用我自己的类型作为泛型参数的标准泛型类型的任何其他自省(introspection)方法:
-
Tuple<int, string>
=> 工作正常 -
Tuple<int, MyType>
=> 异常
我可以从泛型类型定义中获取方法列表:
typeof(Tuple<int, MyType).GetGenericTypeDefinition().GetMethods()
但是,这些方法具有通用占位符而不是实际值(如 T1
、TResult
等),我不想再写一个将通用参数追溯到其原始值的杂乱无章的东西。
代码示例:
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
所以问题是:
- 如何检测类型是否可以安全调用
GetMethods()
和类似的方法? - 如果类型不安全,我如何获得实际的方法列表及其通用参数值?
最佳答案
我在 follow-up question 中得到了答案. TypeBuilder
类有一堆静态重载,这些重载正是这样做的:
var genericTuple = typeof(Tuple<,>);
var myTuple = genericTuple.MakeGenericType(typeof(int), myType);
var ctor = TypeBuilder.GetConstructor(myTuple, genericTuple.GetConstructors().First());
奇怪的是,GetProperty
没有重载。但是,仍然可以使用 GetMethod
解析属性 getter 和 setter:
var genericGetter = typeof(Tuple<,>).GetProperty("Item1").GetMethod;
var actual = TypeBuilder.GetMethod(myTuple, genericGetter);
关于c# - 反射生成的类型和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15646881/