c# - 如何通过 Roslyn 获取类的基类名称?

标签 c# roslyn

我正在使用 Roslyn我有以下类(class):

var source = @"
    using System;
    class MyClass : MyBaseClass {
      static void Main(string[] args) {
        Console.WriteLine(""Hello, World!"");
      }
    }";

// Parsing
SyntaxTree tree = CSharpSyntaxTree.ParseText(source);

// This uses an internal function (working)
// That gets the first node of type `SimpleBaseTypeSyntax`
SimpleBaseTypeSyntax simpleBaseType = GetNBaseClassNode(tree);

获取基类名

我成功地访问了包含我需要的节点SimpleBaseTypeSyntax。事实上,如果我使用语法浏览器,我会得到:

enter image description here

节点 IdentifierToken 拥有我需要的一切,它的 TextValueValueText 属性是 "MyBaseClass"!

但是,虽然在语法资源管理器中我可以看到所有这些值,但我无法以编程方式访问它们。

所以我尝试以编程方式检索节点:

IdentifierNameSyntax identifierNode =
  simpleBaseType.ChildNodes().OfType<IdentifierNameSyntax>().First();
SyntaxToken identifier = simpleBaseType.Identifier;
string name = identifier.Text;

但是 name 是空字符串。与 identifier.Valueidentifier.ValueText 相同。

我做错了什么?也许我做错了,所以您将如何检索基类名称?


另一种尝试:使用语义模型

我开始考虑我需要此类信息的语义模型:

IdentifierNameSyntax identifierNode =
  simpleBaseType .ChildNodes().OfType<IdentifierNameSyntax>().First();

SemanticModel semanticModel =
  CSharpCompilation.Create("Class")
   .AddReferences(MetadataReference.CreateFromFile(
     typeof(object).Assembly.Location))
       .AddSyntaxTrees(tree).GetSemanticModel(tree);

SymbolInfo symbolInfo = this.semanticModel.GetSymbolInfo(identifierNode);
string name = symbolInfo.Symbol.Name;

这将引发异常,因为 symbolInfo.Symbolnull

最佳答案

我其实不知道为什么你不能通过 GetSymbolInfo()BaseTypeSyntax 传递给语义模型,但它也返回 null 对我来说没有错误。

无论如何,这是一种有效的方法:

var tree = CSharpSyntaxTree.ParseText(@"
using System;
class MyBaseClass
{
}
class MyClass : MyBaseClass {
  static void Main(string[] args) {
    Console.WriteLine(""Hello, World!"");
  }
}");

var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);

var myClass = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().Last();
var myClassSymbol = model.GetDeclaredSymbol(myClass) as ITypeSymbol;
var baseTypeName = myClassSymbol.BaseType.Name;

您需要在此处使用语义模型,因为您将无法可靠地判断您在语法级别处理的是接口(interface)还是基类型。

关于c# - 如何通过 Roslyn 获取类的基类名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33090499/

相关文章:

c# - 使用 Roslyn 从 ObjectCreationExpressionSyntax 获取构造函数声明?

c# - 我找不到内联表达式变量的代码

c# - 如何将非成员函数的地址存储在 DWORD 中 (c++)

c# - 我无法从 Controller 中的表单接收发布数据

c# - Windows 身份验证混合

Roslyn:从元模型创建程序集

.net - 编译器管道如何对应增量源生成?

c# - 在 RadGrid 客户端获取选定的项目

c# - 我应该为整数对使用什么数据结构?

c# - 使用自定义脚本函数评估数学表达式