【问题标题】:How to get a run-time type of generic class using roslyn?如何使用 roslyn 获取运行时类型的泛型类?
【发布时间】:2019-02-13 10:37:00
【问题描述】:

例如我有以下类型:

public class MyClass<T>
{
    public T Prop { get; }
}

或者说我有以下方法:

private static void Method<T>() 
{
     //how I can get a real type of <T>
}

如何使用 roslyn 获得运行时类型的泛型类?我的意思是&lt;T&gt;的真实类型

static void Main(string[] args)
{
    // here I need to get int
    var m = new MyClass<int>();

    // here I need to get object
    var m1 = new MyClass<object>();
}

【问题讨论】:

  • @Alexander 我相信 OP 是通过 Rosyln 询问的,而不是在运行时询问
  • 如果我通过roslynquoter 运行它,它会显示为WithTypeArgumentList (i.stack.imgur.com/S4CUf.png) - 您是否在节点下寻找TypeArgumentList 或类似名称?到目前为止,您在 roslyn 代码方面有什么?
  • @MarcGravell 标识符(“T”)
  • @isxaker 你在看这个方法吗?还是在呼叫站点? (呼叫站点=Main);仅在调用站点才定义
  • @MarcGravell 是的,你是对的。它让我Token(SyntaxKind.ObjectKeyword)

标签: c# .net roslyn roslyn-code-analysis


【解决方案1】:

如果你有MyClass 语法树并且你想得到ITypeParameterSymbol T 的具体类型或实例化类型,简单的答案是,你不能用Roslyn 来做。

如果你的意思是如何像new MyClass&lt;int&gt;() 这样从实例化中获取类型,答案是:

var genericType = // the ObjectCreationExpressionSyntax from type GenericNameSyntax
var typArg = genericType.TypeArgumentList.Arguments.First();
var type = model.GetSymbolInfo(typeArg).Symbol // this is your concrete type

您还可以解析TypeArgument 中的IdentifierNameTypeSyntax,但它是语法上的,而不是语义上的。

更新

请说明您希望从哪个角度获取有关运行时类型的信息。

正如我所写,如果您持有 MyClass&lt;T&gt; 的语法树(在您的示例中),您将无法获得任何信息。 Roslyn 可以告诉你这是一个泛型类型,但它。 获取此信息的唯一方法是在运行时(例如,如果您处于调试模式并在此类中的某处设置断点并在监视窗口中检查 T 的类型)。

如果您想从示例中的 var m = new MyClass&lt;int&gt;() 等实例化语法中获取类型,正如我所回答的那样,这很容易。

【讨论】:

  • 我通过 roslyn 需要它。我做不到?证明在哪里?见@MarcGravell 评论
  • Roslyn 是编译器,而不是运行时。您可以进行句法或语义(也包括流)分析,但您不知道哪个是 T 是某个类,因为它可以是任何人。如果您想知道从哪里创建具体类型,当然可以。例如,如果您在 VS 的调试会话中,您可以将 T 放在监视窗口中并查看具体类型,因为您有一个具体的 T,但当您有通用 T 时则不行。
  • @isxaker 我希望我能理解你想要达到的目标,否则,试着解释你的问题,我会提供帮助。
  • 谢谢。你答对了。我试图得到 T 的确切类型。所以分析我自己的代码。分析我的方法的所有调用链对我有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多