从Roslyn中的符号获取类型 [英] Getting type from a symbol in roslyn

查看:156
本文介绍了从Roslyn中的符号获取类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is the best general purpose way to get a System.Type from Microsoft.CodeAnalysis.ISymbol for different types of symbols ? (e.g. class declarations, variable, properties, etc)

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

I want to be able to do various checks on the type e.g. as checking if the type implements any interface or is cast-able to any interface, just like one can check on System.Type.

我遇到的问题是用于表示符号的具体类的内部是内部的(请参见 http://sourceroslyn.io/ ),我可以在ISymbol中找不到轮胎类型信息。

The problem I am having is that most of the concrete classes used to represent the symbol are internal (see http://sourceroslyn.io/) and I could not find tye type information in the ISymbol.


  • SourceNamedTypeSymbol

  • LocalSymbol

我使用以下代码检索ISymbol

I retrieve the ISymbol using the following code

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


推荐答案

简短答案:您不能。没有正确的方法从 ISymbol (罗斯林)获取 System.Type (反射)。

Short answer: you can't. There is no proper way to get a System.Type (reflection) from an ISymbol (Roslyn).

要做的一个选择是构造您类型的标准名称,然后通过反射查找(示例)。

One option to do go in the direction you want is constructing the fully-qualified name of your type and then looking that up through reflection (example).

您可能首先应该问自己,这是否是您需要做的事情-反射和Roslyn并不是真的打算一起工作。

You should probably ask yourself whether this is something you need to do in the first place though -- reflection and Roslyn aren't really intended to work together.

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

What you are interested in, however, can be done through Roslyn as well. The key here is using the semantic model which has all this information for you. All declarations (opposed to usages) have a specific overload available that allows you to get the declaring symbol and return it in the appropriate type (such as INamedTypeSymbol in this case).

采用以下示例:

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));

这将显示该类实现的所有接口。但是请记住,这只是引用当前的定义-如果您还对基本类型感兴趣,则必须自己遍历层次结构。

This will display all the interfaces the class implements. Keep in mind however that this just refers to the current definition -- if you're also interested in base types you'll have to go through the hierarchy yourself.

在您的方案,您应该可以将其转换为正确的类型(假设您正在检查声明节点):

In your scenario you should be able to just cast it to the right type (assuming you are checking a declaration node):

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

这篇关于从Roslyn中的符号获取类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆