从罗斯林的符号中获取类型

对于不同类型的符号,从Microsoft.CodeAnalysis.ISymbol获取System.Type的最佳通用方法是什么? (例如类声明,变量,属性等)

我希望能够对类型进行各种检查,例如检查类型是否实现任何接口,或者是否可以转换为任何接口,就像可以检查System.Type一样。

我遇到的问题是,用于表示符号的大多数具体类都是内部的(请参阅http://source.roslyn.io/ ),我在ISymbol中找不到tye类型信息。

  • SourceNamedTypeSymbol
  • LocalSymbol

我使用以下代码检索ISymbol

var objectSymbol = (ISymbol)model.GetDeclaredSymbol(obj.Node); 

简答:你不能。 没有正确的方法从ISymbol (Roslyn)获取System.Type (reflection)。

在你想要的方向上做的一个选择是构建你的类型的完全限定名称,然后通过reflection查看( 示例 )。

你应该问问自己,这是否是你需要做的事情 – 反思和罗斯林并不是真正想要一起工作。

但是,您感兴趣的内容也可以通过Roslyn完成。 这里的关键是使用语义模型,它具有所有这些信息。 所有声明(与使用相对)都有一个特定的重载,允许您获取声明符号并以适当的类型返回它(例如在这种情况下为INamedTypeSymbol )。

采用以下示例:

 const string source = @" using System; namespace MyNamespace { class MyClass : IDisposable { void Method() { MyClass nameOfVariable, another; } } } "; var tree = CSharpSyntaxTree.ParseText(source); var compilation = CSharpCompilation.Create("MyCompilation", new[] { tree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }); var semanticModel = compilation.GetSemanticModel(tree); var root = tree.GetRoot(); var classSymbol = semanticModel.GetDeclaredSymbol(root.DescendantNodes().OfType().First()); Console.WriteLine(string.Join(", ", classSymbol.AllInterfaces)); 

这将显示该类实现的所有接口。 但请记住,这只是指当前的定义 – 如果您对基类型也感兴趣,则必须自己完成层次结构。

在您的场景中,您应该能够将其强制转换为正确的类型(假设您正在检查声明节点):

 var objectSymbol = (INamedTypeSymbol) model.GetDeclaredSymbol(obj.Node);