gpt4 book ai didi

c# - 如何使用 Roslyn 生成类字段的初始化

转载 作者:太空狗 更新时间:2023-10-29 21:32:53 28 4
gpt4 key购买 nike

我知道如何在方法中创建局部变量,例如:

LocalDeclarationStatement(VariableDeclaration(IdentifierName("MyClass"))
.WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("nameOfvariable"))
.WithInitializer(
EqualsValueClause(
ObjectCreationExpression(IdentifierName("MyClass")).WithArgumentList(arguments)
.WithNewKeyword(Token(SyntaxKind.NewKeyword)))))));

会给我:

MyClass nameOfvariable = new MyClass();

但是假设我已经创建了一个字段,现在我只想像这样初始化它(在方法、构造函数或任何东西中):

nameOfVariable = new MyClass();

我该怎么做?我猜它与 VariableDeclerator 有关,但我找不到正确的方法,所以我可以将它添加到包含 StatementSyntaxes 的列表中。我也可以将 VariableDecleration 更改为 "VariableDeclaration(IdentifierName(""))"但这给了我一个难看的语句前面的额外空间。

我似乎在努力了解 Roslyn 的一些非常基本的东西,我尝试检查 http://roslynquoter.azurewebsites.net/但这感觉像是强制执行的方式(感觉它创建了比必要的多得多的代码)。

更新:应该说明我知道如何创建方法/构造函数。当我只能访问字段名称和字段类型时,我只是在寻找一种初始化字段的方法。所以我想生成的唯一代码是这样的:

myField = new MyField();

最佳答案

好吧,您就快完成了,您只需要创建所有这些。这应该做你感兴趣的事情:

const string source = @"
using System;

class MyClass
{
void Method()
{
MyClass nameOfVariable;
}
}
";
var tree = CSharpSyntaxTree.ParseText(source);
var compilation = CSharpCompilation.Create("MyCompilation", new[] { tree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) });
var semanticModel = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();

var local = root.DescendantNodes().OfType<LocalDeclarationStatementSyntax>().First();
var declaration = local.Declaration;
var declarator = declaration.Variables.First();

var identifier = SyntaxFactory.IdentifierName("MyClass");
var objectCreationExpression = SyntaxFactory.ObjectCreationExpression(identifier, SyntaxFactory.ArgumentList(), null);
var equalsValueClause = SyntaxFactory.EqualsValueClause(objectCreationExpression);
var newDeclarator = declarator.WithInitializer(equalsValueClause).WithAdditionalAnnotations(Formatter.Annotation);
var newRoot = root.ReplaceNode(declarator, newDeclarator);
var formattedRoot = Formatter.Format(newRoot, Formatter.Annotation, new AdhocWorkspace());

Console.WriteLine(formattedRoot.GetText());
Console.Read();

一些解释:您创建了一个新的标识符 MyClass,它将在您的 ObjectCreationExpression 中使用。然后将所有内容包装在 EqualsValueClause 中,并将其设置为声明符的初始值设定项。我们还向该节点添加了 Formatter 注释,以便稍后对其进行格式化,而不会出现空白问题。

剩下的就是替换原始树中的节点,格式化它,然后就完成了:

enter image description here

-------------------------------------------- ----------------------------------

如果您的意思是您想要将赋值与声明分开,那么您必须创建一个新的 AssignmentExpression 并将其包装在 ExpressionStatement 中。通常表达式和语句是不同的概念,但此 ExpressionStatement 允许我们将表达式视为语句,这很重要,因为方法的主体只接受语句。

在代码中,它看起来像这样:

internal static void Execute()
{
const string source = @"
using System;

class MyClass
{
void Method()
{
MyClass nameOfVariable, another;
}
}
";
var tree = CSharpSyntaxTree.ParseText(source);
var compilation = CSharpCompilation.Create("MyCompilation", new[] { tree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) });
var semanticModel = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();

var local = root.DescendantNodes().OfType<LocalDeclarationStatementSyntax>().First();
var method = local.Ancestors().OfType<MethodDeclarationSyntax>().First();

var variableIdentifier = SyntaxFactory.IdentifierName("nameOfVariable");
var classIdentifier = SyntaxFactory.IdentifierName("MyClass");
var objectCreationExpression = SyntaxFactory.ObjectCreationExpression(classIdentifier, SyntaxFactory.ArgumentList(), null);
var assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, variableIdentifier, objectCreationExpression);
var expressionStatement = SyntaxFactory.ExpressionStatement(assignment).WithAdditionalAnnotations(Formatter.Annotation);
var newMethod = method.AddBodyStatements(expressionStatement);

var newRoot = root.ReplaceNode(method.Body, newMethod.Body);
var formattedRoot = Formatter.Format(newRoot, Formatter.Annotation, new AdhocWorkspace());

Console.WriteLine(formattedRoot.GetText());
Console.Read();
}

结果:

enter image description here

关于c# - 如何使用 Roslyn 生成类字段的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34532515/

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