C# 我的注解在哪里?

C# 我的注解在哪里?,c#,roslyn,C#,Roslyn,当我尝试注释类、属性和方法,然后尝试检索注释节点时,只返回类1。为什么? 下面是注释的代码 SyntaxAnnotation propertyAnnotation = null; SyntaxAnnotation classAnnotation = null; SyntaxAnnotation setMethodAnnotation = null; document = document .AnnotateClass(classDeclaration, out classAnnotat

当我尝试注释类、属性和方法,然后尝试检索注释节点时,只返回类1。为什么?

下面是注释的代码

SyntaxAnnotation propertyAnnotation = null;
SyntaxAnnotation classAnnotation = null;
SyntaxAnnotation setMethodAnnotation = null;

document = document
    .AnnotateClass(classDeclaration, out classAnnotation)
    .AnnotateProperty(propertyDeclaration, out propertyAnnotation)
    .AnnotateSetMethod(setMethodDeclaration, out setMethodAnnotation);
我在IDocument上定义了这些扩展方法

    internal static IDocument AnnotateSetMethod(this IDocument document, MethodDeclarationSyntax method,
                                                                        out SyntaxAnnotation annotation)
    {
        annotation = new SyntaxAnnotation();

        var newRoot = document.GetSyntaxRoot()
                                .ReplaceNode(method, method.WithAdditionalAnnotations(annotation));

        return document.UpdateSyntaxRoot(newRoot);

    }

    internal static IDocument AnnotateProperty(this IDocument document, PropertyDeclarationSyntax property,
                                               out SyntaxAnnotation annotation)
    {
        annotation = new SyntaxAnnotation();

        var newRoot = document.GetSyntaxRoot()
                                .ReplaceNode(property, property.WithAdditionalAnnotations(annotation));

        return document.UpdateSyntaxRoot(newRoot);
    }

    internal static IDocument AnnotateClass(this IDocument document, ClassDeclarationSyntax classDeclaration,
                                              out 

        SyntaxAnnotation annotation)
        {
            annotation = new SyntaxAnnotation();

            var newRoot = document.GetSyntaxRoot()
                                    .ReplaceNode(classDeclaration, classDeclaration.WithAdditionalAnnotations(annotation));

            return document.UpdateSyntaxRoot(newRoot);
        }

public static TSyntaxNode GetAnnotatedNode<TSyntaxNode>(this IDocument document, SyntaxAnnotation annotation)
                where TSyntaxNode : CommonSyntaxNode
            {
                return document.GetSyntaxRoot().GetAnnotatedNode<TSyntaxNode>(annotation);
            }
内部静态IDocument AnnotateSetMethod(此IDocument文档,MethodDeclarationSyntax方法,
输出语法(注释)
{
annotation=新的SyntaxAnnotation();
var newRoot=document.GetSyntaxRoot()
.ReplaceNode(方法,方法.带有附加注释(注释));
返回文档。UpdateSyntaxRoot(newRoot);
}
内部静态IDocument AnnotateProperty(此IDocument文档、PropertyDeclarationSyntax属性、,
输出语法(注释)
{
annotation=新的SyntaxAnnotation();
var newRoot=document.GetSyntaxRoot()
.ReplaceNode(property,property.withAdditionalAnnotation(annotation));
返回文档。UpdateSyntaxRoot(newRoot);
}
内部静态IDocument AnnotateClass(此IDocument文档、ClassDeclarationSyntax classDeclaration、,
出来
语法注释(注释)
{
annotation=新的SyntaxAnnotation();
var newRoot=document.GetSyntaxRoot()
.ReplaceNode(classDeclaration,classDeclaration.withAdditionalAnnotation(annotation));
返回文档。UpdateSyntaxRoot(newRoot);
}
公共静态TSyntaxNode GetAnnotatedNode(此IDocument文档,SyntaxAnnotation)
其中TSyntaxNode:CommonSyntaxNode
{
返回文档.GetSyntaxRoot().GetAnnotatedNode(注释);
}
如果我这样做了

var propertyDeclaration = document.GetAnnotatedNode<PropertyDeclarationSyntax>(propertyAnnotation);
var-propertyDeclaration=document.GetAnnotatedNode(propertyAnnotation);

我得到了一个错误,但是如果我尝试使用ClassDeclarationSyntax,它就可以正常工作

我的crystal ball告诉我,除了您的Annotated类之外,其他所有类中的.Replace节点调用都失败了。查看您返回的新根是否与旧根完全相同

这是因为一旦您向类添加了注释,现在就有了一个新的树,因此您的属性语法不再“在”该树中——它是一个新节点。这就是不变性的方式——一旦在某个地方创建了一个新节点,树中的所有节点实际上都是新的,因为您可以从任何其他节点访问任何节点。(正是因为这个问题,我们首先添加了语法注释……否则您将创建一些节点,并且无法返回到它们。)

您有几种方法来实现这一点:

  • 使用SyntaxRewriter,您可以在一个阶段完成全部重写。您可以覆盖VisitClass、VisitProperty等,并同时生成带有注释的新节点
  • 不要调用ReplaceNode,而是调用ReplaceNodes,在这里您可以同时替换所有三个节点
  • 在这两种情况下,出于性能原因,单次重写总是比多次重写更可取。正如我所说,一旦您替换树中的一个节点并返回一个新根,您的所有实例都已更改,可能需要重新创建。这很昂贵,并且会产生内存压力


    [从技术上讲,这句话是一个谎言:我们确实是懒洋洋地构建东西,重复使用很多东西。但重写越少越好。]

    我知道按照您所描述的做会更有效率,但我试图了解创建新节点时注释会发生什么情况?假设我在类声明上创建了一个注释,然后将该注释传递给另一个对属性进行注释的方法。如果我找到了类声明并注释了属性,然后替换了类节点,那么我的类注释就消失了。也许如果我能给你看代码会更容易。。。