我知道如何在方法内部创建局部变量,例如:
LocalDeclarationStatement(VariableDeclaration(IdentifierName("MyClass"))
.WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("nameOfvariable"))
.WithInitializer(
EqualsValueClause(
ObjectCreationExpression(IdentifierName("MyClass")).WithArgumentList(arguments)
.WithNewKeyword(Token(SyntaxKind.NewKeyword)))))));
Run Code Online (Sandbox Code Playgroud)
会给我:
MyClass nameOfvariable = new MyClass();
Run Code Online (Sandbox Code Playgroud)
但是说我已经创建了一个字段,现在我只想像这样初始化它(在方法,构造函数或任何东西中):
nameOfVariable = new MyClass();
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?我猜这与VariableDeclerator有关,但是我找不到正确的方法,因此可以将其添加到包含StatementSyntaxes的列表中。我也可以将VariableDecleration更改为“ VariableDeclaration(IdentifierName(”“))”“,但这在语句的前面给了我一个丑陋的额外空间。
似乎我在与Roslyn的一些非常基础的东西斗争,我尝试检查http://roslynquoter.azurewebsites.net/,但这听起来像是强制的方式(感觉它创建了很多不必要的代码)。
更新:应该澄清一下,我知道如何创建方法/构造函数。当我只能访问字段名称和字段类型时,我只是在寻找一种初始化字段的方法。因此,我要生成的唯一代码是:
myField = new MyField();
Run Code Online (Sandbox Code Playgroud)
好了,您快要准备好了,您只需要创建所有内容即可。这应该做您感兴趣的事情:
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();
Run Code Online (Sandbox Code Playgroud)
一些说明:您创建一个新的标识符MyClass,该标识符将在您的中使用ObjectCreationExpression。然后,将所有内容包装在中,EqualsValueClause并将其设置为声明程序的初始化程序。我们还将Formatter注释添加到该节点,以便以后可以对其进行格式化,而不会出现空格问题。
然后剩下的就是替换原始树中的节点,对其进行格式化,然后完成:
如果您是想将分配与声明分开放置,则必须创建一个新分配并将其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();
}
Run Code Online (Sandbox Code Playgroud)
结果:
| 归档时间: |
|
| 查看次数: |
2075 次 |
| 最近记录: |