如何从SemanticModel为新创建的类获取声明的符号?

DeC*_*Caf 8 c# roslyn .net-4.6

ISymbolClassDeclaration我刚刚创建的那个中获取一个最简单的方法是什么?

请考虑以下代码:

AdhocWorkspace workspace = new AdhocWorkspace();         
Project project = workspace.AddProject("Test", LanguageNames.CSharp);

ClassDeclarationSyntax classDeclaration = SyntaxFactory.ClassDeclaration("MyClass");
CompilationUnitSyntax compilationUnit = SyntaxFactory.CompilationUnit().AddMembers(classDeclaration);         
Document document = project.AddDocument("Test.cs", compilationUnit);
SemanticModel semanticModel = await document.GetSemanticModelAsync();
ISymbol symbol = semanticModel.GetDeclaredSymbol(classDeclaration); // <-- Throws Exception
Run Code Online (Sandbox Code Playgroud)

最后一行抛出一个异常,说" 语法节点不在语法树中 ".

我想我需要ClassDeclarationSyntax从新的那里再次获得我刚创建的那个SyntaxTree.但是,在新的SyntaxTree给定中,只有旧的才能找到它的最简单的方法是什么ClassDeclarationSyntax

在上面的例子中,类是唯一的类,SyntaxTree并且是第一个子类CompilationUnit,因此在这个简单的情况下很容易找到它.但是想象一下语法树包含很多声明的情况,这些声明可能是嵌套的,并且所寻求的类声明嵌套在内部?有没有办法用旧的ClassDeclarationSyntax方法找到新的?(或者我在这里做错了什么?)

Jos*_*rty 8

您可以使用a SyntaxAnnotation来跟踪您的类节点:

AdhocWorkspace workspace = new AdhocWorkspace();
Project project = workspace.AddProject("Test", LanguageNames.CSharp);

//Attach a syntax annotation to the class declaration
var syntaxAnnotation = new SyntaxAnnotation("ClassTracker");
var classDeclaration = SyntaxFactory.ClassDeclaration("MyClass")
    .WithAdditionalAnnotations(syntaxAnnotation);

var compilationUnit = SyntaxFactory.CompilationUnit().AddMembers(classDeclaration);

Document document = project.AddDocument("Test.cs", compilationUnit);
SemanticModel semanticModel = document.GetSemanticModelAsync().Result;

//Use the annotation on our original node to find the new class declaration
var changedClass = document.GetSyntaxRootAsync().Result.DescendantNodes().OfType<ClassDeclarationSyntax>()
    .Where(n => n.HasAnnotation(syntaxAnnotation)).Single();
var symbol = semanticModel.GetDeclaredSymbol(changedClass);
Run Code Online (Sandbox Code Playgroud)

无论您最终添加课程的复杂文档是什么,这都应该有效.