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

时间:2016-01-12 15:15:17

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

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

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

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

  • SourceNamedTypeSymbol
  • LocalSymbol

我使用以下代码检索ISymbol

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

2 个答案:

答案 0 :(得分:13)

简短回答:你不能。没有正确的方法从System.Type(Roslyn)获得ISymbol(反射)。

按照您想要的方向前进的一个选项是构建类型的完全限定名称,然后通过反射查找(example)。

你应该问问自己这是否是你首先需要做的事情 - 反思和罗斯林并不打算一起工作。

然而,您感兴趣的内容也可以通过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<ClassDeclarationSyntax>().First());
Console.WriteLine(string.Join(", ", classSymbol.AllInterfaces));

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

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

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

答案 1 :(得分:1)

我认为这就是您想要的:

var castedProperty = (IPropertySymbol) property;
var type = castedProperty.Type.Name;

**变量“属性”是ISymbol实例。