如何使用Roslyn正确修改类声明语法?

时间:2016-03-14 14:37:30

标签: c# roslyn

我有一个方法来修改类声明语法。我在类中的所有方法中添加了两个StatementSyntax属性,然后我将该类保存到我的解决方案中。一切都很好,但方法ReplaceNode仅适用于第一种方法ListOfMethod。我方法的哪一部分不正确?

private ClassDeclarationSyntax GetNewClass(ClassDeclarationSyntax c)
{
    List<MethodDeclarationSyntax>  ListOfMethod = lom(c);
    foreach (var OldMethod in ListOfMethod )
    {
        MethodDeclarationSyntax NewMethod = GetNewMethod (OldMethod);
        c = c.ReplaceNode(OldMethod,NewMethod);
    }
    return c;
}

2 个答案:

答案 0 :(得分:5)

在Roslyn中,大多数数据结构都是不可变的,所以当你在某个东西上调用一个修改方法时,那个操作就会返回一个新的修改过的对象,而不是就地进行修改。

因此,在您的情况下,您将从给定的ClassDeclarationSyntax收集您感兴趣的所有方法。当你调用ReplaceNode时,它会返回一个新的类声明。这个新的类声明不会包含您之前找到的任何方法,因为它是一个新的类声明实例。

一种选择是使用ReplaceNodes在一次通话中进行更改,在您的情况下,这似乎是要遵循的方法。

另一种选择是尝试使用在树修改期间不会丢失的永久标记来标记方法。为此,您可以使用WithAdditionalAnnotations()向节点添加注释,然后您可以在树中找到具有给定注释的给定节点。

答案 1 :(得分:0)

我改变了下面的方法。每次我使用方法ReplaceNode时都会创建新的classdeclarationsyntax然后我必须从这个新的方法获得下一个MethodDeclarationSyntax

into Count =c.Members.OfType <MethodDeclarationSyntax>().Count();
for  (int i=0;i <Count; i++)
{
    List <MethodDeclarationSyntax > l=c.Members.OfType <MethodDeclarationSyntax>().ToList();
    MethodDeclarationSyntax NewMethod=GetNewMethod (l [i]);
    c=c.ReplaceNode(l [i],NewMethod);
}