gpt4 book ai didi

c# - 使用 Roslyn 排序构造函数参数

转载 作者:太空宇宙 更新时间:2023-11-03 21:20:42 26 4
gpt4 key购买 nike

我正在尝试创建对构造函数参数进行排序的方法。它可以很好地导航甚至更新树,但序列化文本包含原始参数:

    static void Transform(string sourceCode)
{
var tree = CSharpSyntaxTree.ParseText(sourceCode);

var root = (CompilationUnitSyntax)tree.GetRoot();

var @namespace = (NamespaceDeclarationSyntax)
root.ChildNodes().First(n => n.Kind() == SyntaxKind.NamespaceDeclaration);

var @class = (ClassDeclarationSyntax)
@namespace.ChildNodes().First(n => n.Kind() == SyntaxKind.ClassDeclaration);

var constructor = (ConstructorDeclarationSyntax)
@class.ChildNodes().First(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

var parameters = constructor.ParameterList
.ChildNodes()
.Cast<ParameterSyntax>()
.OrderBy(node => ((IdentifierNameSyntax) node.Type).Identifier.ToString())
.Select(node => SyntaxFactory.Parameter(
SyntaxFactory.List<AttributeListSyntax>(),
SyntaxFactory.TokenList(),
SyntaxFactory.ParseTypeName(((IdentifierNameSyntax)node.Type).Identifier.Text),
SyntaxFactory.Identifier(node.Identifier.Text),
null));

var updatedParameterList = SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters));

((SyntaxNode)constructor).ReplaceNode(constructor.ParameterList, updatedParameterList);

Console.WriteLine(root.GetText().ToString());
}

我这样调用它:

        Transform(@"
namespace Test {
class Test {
Test(IParam2 param2, IParam1 param1) { }
}
}");

并期望有

namespace Test {
class Test {
Test(IParam1 param1, IParam2 param2) { }
}
}

但输出的参数顺序仍然错误。有什么想法吗?

最佳答案

问题是 Roslyn 中的所有树都是不可变的。

令人惊讶的是,这一行实际上并没有做任何事情:

((SyntaxNode)constructor).ReplaceNode(constructor.ParameterList, updatedParameterList);

那是因为 ReplaceNode() 返回一个全新的语法树,并且不操作旧语法树。

这就是您要找的:

static void TransformParameterOrder(string sourceCode)
{
var tree = CSharpSyntaxTree.ParseText(sourceCode);

var root = (CompilationUnitSyntax)tree.GetRoot();

var @namespace = (NamespaceDeclarationSyntax)
root.ChildNodes().First(n => n.Kind() == SyntaxKind.NamespaceDeclaration);

var @class = (ClassDeclarationSyntax)
@namespace.ChildNodes().First(n => n.Kind() == SyntaxKind.ClassDeclaration);

var constructor = (ConstructorDeclarationSyntax)
@class.ChildNodes().First(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

var child = constructor.ParameterList.ChildNodes().Count();

var parameters = constructor.ParameterList
.ChildNodes()
.Cast<ParameterSyntax>()
.OrderBy(node => ((IdentifierNameSyntax)node.Type).Identifier.ToString())
.Select(node => SyntaxFactory.Parameter(
SyntaxFactory.List<AttributeListSyntax>(),
SyntaxFactory.TokenList(),
SyntaxFactory.ParseTypeName(((IdentifierNameSyntax)node.Type).Identifier.Text),
SyntaxFactory.Identifier(node.Identifier.Text),
null))
.Take(2);

var updatedParameterList = SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters));

var newNode = ((SyntaxNode)constructor).ReplaceNode(constructor.ParameterList, updatedParameterList);
//Alternatively you can assign root = root.ReplaceNode...
var newRoot = root.ReplaceNode(constructor.ParameterList, updatedParameterList);

Console.WriteLine(root.GetText().ToString());
Console.WriteLine(newRoot.GetText().ToString());
}

关于c# - 使用 Roslyn 排序构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30986360/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com