c# - 反射生成的类型和泛型

标签 c# reflection.emit

我与 Reflection.Emit 又经历了一个不愉快的时刻和类型管理。

比如说,我有一个名为 MyType 的类型这是在动态生成的程序集中定义的。 打电话MyType.GetMethods()结果 NotSupportedException ,这让我不得不编写自己的包装器和查找表集。然而,当我调用 GetMethods() 时,同样的事情发生了。或使用我自己的类型作为泛型参数的标准泛型类型的任何其他自省(introspection)方法:

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

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

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

但是,这些方法具有通用占位符而不是实际值(如 T1TResult 等),我不想再写一个将通用参数追溯到其原始值的杂乱无章的东西。

代码示例:

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

所以问题是:

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

最佳答案

我在 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/

相关文章:

c# - 程序未按预期运行

c# - InternalsVisibleTo 用于动态生成的程序集,但具有强大的命名

c# - LINQ 表达式和这个

c# - 如何发出对 [mscorlib]System.Console::Write(char) 的调用?

c# - 将每个方法包装在 try-catch block 中会使程序变慢多少?

c# - 用 C# 正则表达式替换字符串模式

c# - 计算测量转换

.net - 如何使用 Reflection.Emit 注入(inject)文字表达式?

c# - 使用 IL Emit 替换 Activator.CreateInstance

c# - ApplicationException 或创建自定义异常?