Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反射生成和泛型类型_C#_Reflection.emit - Fatal编程技术网

C# 反射生成和泛型类型

C# 反射生成和泛型类型,c#,reflection.emit,C#,Reflection.emit,我在Reflection.Emit和类型管理方面又遇到了一个棘手的时刻 比如说,我有一个名为MyType的类型,它是在动态生成的程序集中定义的。 调用MyType.GetMethods()会导致NotSupportedException,这使我不得不编写自己的包装器和查找表集。但是,当我调用标准泛型类型上的GetMethods()或任何其他内省方法(使用我自己的类型作为泛型参数)时,也会发生同样的情况: Tuple=>工作正常 元组=>异常 我可以从泛型类型定义中获取方法列表: typeof

我在
Reflection.Emit
和类型管理方面又遇到了一个棘手的时刻

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

  • Tuple
    =>工作正常
  • 元组
    =>异常
我可以从泛型类型定义中获取方法列表:


typeof(Tuple我会让您参考文档:

上面说

虽然TypeBuilder是从Type派生的,但Type类中定义的某些抽象方法在TypeBuilder中没有完全实现。这些TypeBuilder方法引发NotSupportedException。可以通过使用Type.GetType或Assembly.GetType检索创建的类型并反映检索到的typ来获得所需的功能e

因此:

如何检测一个类型是否可以安全地调用GetMethods()和类似的方法

如果类型对象是TypeBuilder,或者如果该类型引用的是TypeBuilder的任何类型,那么这样做是不安全的

如果类型不安全,如何获取方法的实际列表及其泛型参数值


我会再次让您参考文档。实际上,将类型发送到程序集中,然后将其从程序集中取出。

我在a中得到了答案。
TypeBuilder
类有一系列静态重载,它们完全可以完成以下任务:

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

请编辑您的问题,以包含一个简短但完整的程序来演示该问题。此外,请提供有关
NotSupportedException
的更多详细信息-消息中是否没有任何内容?@JonSkeet,异常只是说“该方法不受支持”或者类似的东西。我正在运行一个俄文版的Windows,所以我不知道确切的消息,但它不包含其他信息。stacktrace只有我的
GetMethods()
System.Reflection.Emit.TypeBuilderInstantiation.GetMethods(BindingFlags bindingAttr)
在它里面。如果您需要那些
MethodInfo
s(等),因为您仍然忙于构建类型,那么实际上您必须跟踪原始的
MethodBuilder
s(等),以便在方法调用和其他发出的调用中使用。如果您需要
MethodInfo
s(等)在您已经调用了
CreateType
之后,然后,正如Eric回答的那样,您可以在创建的类型上调用这些方法。@KirkWoll,我正在忙于构建另一个类型。例如,我有类型
A
B
。type
B
有一个使用
Tuple
的方法,需要从中获取
Tuple.Item1
。我已经检测
tuple
变量的类型并调用
GetProperties()
在它上面。没有要跟踪的
MethodBuilder
,因为我没有定义这个类型,只是通过应用泛型参数来实例化它。@JonSkeet,我添加了一小段代码。检查一个类型是否是
TypeBuilder
很容易,但是我如何检查一个类型是否引用了
TypeBuilder
?@Impworks:为什么你需要检查一下吗?只需完成所有类型构建,发出程序集,然后开始使用类型。你的更大目标并不清楚,但Eric的建议对我来说似乎是前进的方向。至于将类型发出到程序集中的想法,类型可能是相互依赖的。例如,
A
使用
列表
B
使用一个
列表
。我不能完全发出这两种类型并用
CreateType
@Impworks完成它:为什么需要使用
GetMethods()
在定义这些类型时?定义这两个类型,然后发出程序集,然后对它们执行任何您需要的操作。听起来这里有很多上下文您还没有包含在您的问题中。@Impworks:啊,现在我们来讨论一下。Reflection.emit太弱了,无法用于构建真正的编译器。它非常适合小玩具编译sks喜欢在LINQ查询中发出动态调用站点和表达式树,但是对于编译器中遇到的各种问题,您很快就会超出它的能力。请使用CCI,而不是Reflection.Emit。
var genericTuple = typeof(Tuple<,>);
var myTuple = genericTuple.MakeGenericType(typeof(int), myType);
var ctor = TypeBuilder.GetConstructor(myTuple, genericTuple.GetConstructors().First());
var genericGetter = typeof(Tuple<,>).GetProperty("Item1").GetMethod;
var actual = TypeBuilder.GetMethod(myTuple, genericGetter);