当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何使用Roslyn生成类字段的初始化》经验,为你挑选了1个好方法。

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

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();

Jeroen Vanne.. 5

好了,您快要准备好了,您只需要创建所有内容即可。这应该做您感兴趣的事情:

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().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注释添加到该节点,以便以后可以对其进行格式化,而不会出现空格问题。

然后剩下的就是替换原始树中的节点,对其进行格式化,然后完成:

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

如果您是想将分配与声明分开放置,则必须创建一个新分配并将其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().First();
    var method = local.Ancestors().OfType().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();
}

结果:



1> Jeroen Vanne..:

好了,您快要准备好了,您只需要创建所有内容即可。这应该做您感兴趣的事情:

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().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注释添加到该节点,以便以后可以对其进行格式化,而不会出现空格问题。

然后剩下的就是替换原始树中的节点,对其进行格式化,然后完成:

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

如果您是想将分配与声明分开放置,则必须创建一个新分配并将其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().First();
    var method = local.Ancestors().OfType().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();
}

结果:

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有