我知道如何在方法内部创建局部变量,例如:
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(); }
结果:
好了,您快要准备好了,您只需要创建所有内容即可。这应该做您感兴趣的事情:
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(); }
结果: