【问题标题】:Get the implicitly instantiated generic types in from an assembly?从程序集中获取隐式实例化的泛型类型?
【发布时间】:2023-03-21 09:51:01
【问题描述】:

我正在尝试使用 C# 反射从程序集中检索所有类型(比方说:从“ExecutingAssembly”),我可以检索所有显式定义的类型,包括我的泛型类型在程序集中定义。但我似乎无法检索 隐式 实例化的泛型类型(具体版本)。

例如,var types = Assembly.GetExecutingAssembly().GetTypes(); 这将检索所有显式定义的类型(在此程序集中定义的类、结构,包括通用类型,例如class MyGenericClass<T>)。

然而,在同一个程序集中,我实际上在我的代码中使用MyGenericClass<int>作为concrete类型来实际实例化对象(例如:MyGenericClass<int> myObject;),但是这个具体 MyGenericClass<int> 类型似乎不能被上面的代码检索到。

我想知道是否有任何实例化生成的类型实际上可以从程序集中检索,所以我以后可能会使用该类型进行一些代码生成工作。

如果它们不可检索,有什么设计建议吗?

提前谢谢你!

【问题讨论】:

  • 具体类型在使用之前不会被创建。除了一些 AOT 场景外,运行时在实际命中引用它的代码之前并不知道您将创建一个新的 MyGenericClass<int>
  • "...我可以使用那种类型..." - .NET 泛型设计的要点之一是它们必须使用其声明的类型约束允许的任何可能类型。您不需要其他人事先使用特定组合。
  • 您真正想解决什么问题为什么您需要这些信息? “一些代码生成工作”实际上意味着什么?
  • 您能否向我们展示一个您希望查看其类型信息的代码示例?
  • 如果你有public static MyGenericClass<T> CreateMyGenericClass<T>() { return new MyGenericClass<T>(); } 方法,你想获得什么信息?你不知道调用者会传入什么。或者更糟糕的是,你的代码中某处有一些MakeGenericType() 反射魔法?实际的封闭泛型类型将由运行时在运行时创建。你有一个 XY 问题。正如@canton 所说,说明您要解决的实际问题。

标签: c# generics reflection .net-assembly


【解决方案1】:

反射基于程序集的元数据。您似乎想要的需要涉及某种源代码检查,以找出在运行时创建的所有具体泛型类型。可能的?是的,编译器会这样做,但不是反射。

【讨论】:

  • 不可能总是 - 特别是反射会使事情难以分析。
  • @canton7 哦,是的,如果程序集通过反射创建类型,那么追踪起来根本不容易。但我敢打赌,OP 是在询问代码中显式类型的泛型类型。不过不太确定他为什么需要这些信息。
  • 阅读这个答案两次,检查非常接近我的观察 - 关键点:编译器应该知道
【解决方案2】:

这不是您所追求的,但您可以更深入地获取所有类型的所有方法并收集所有返回类型和所有参数的类型。

需要明确的是,这与您的任务所需的代码分析相差无几。这只是为您提供更多信息。

【讨论】:

  • 不是我的反对意见,但这并不能说明 in 该方法中使用的类型。一个void仍然可以使用本地的List<T>变量,OP在后者之后。
  • 如果答案是“与您的任务所需的代码分析没有任何关系”,也许它不应该是一个答案?也许应该是评论。
  • 当然!如果我给人的印象是这会分析代码,那我就失败了,因为这不是我的本意:)
  • 您认为 Eric L. 会看到这个问题并添加答案吗?
  • 也不是我的反对票 ;-) (我实际上喜欢看到一个答案被反对票的原因,一般来说)
猜你喜欢
  • 2018-01-29
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2011-04-02
  • 1970-01-01
相关资源
最近更新 更多