我想使用以下类作为一个具体示例逐步构建一个新的IDocument对象。您可以从任何您喜欢的对象开始,并使用您喜欢的任何中间对象,只要生成的对象是一个IDocument,它代表最后的完整类。
步骤1:添加一个名为MyNamespace的新命名空间。 打印出当前对象应该如下所示:
namespace MyNamespace
{
}
步骤2:向名为MyClass的名称空间添加一个新类。 打印出当前对象应该如下所示:
namespace MyNamespace
{
public class MyClass
{
}
}
步骤3:向此类添加一个名为MyMethod的新方法。 打印出当前对象应该如下所示:
namespace MyNamespace
{
public class MyClass
{
public void MyMethod()
{
}
}
}
我遇到的问题是,理论上似乎有很多方法可以解决这个问题,或者至少错误地认为你可以解决这个问题。各种不同对象中的无尽方法和构造函数,如WithChanges,UpdateDocument,各种语法对象上的方法,ParseCompilationUnit等。
基本上,我想以增量的方式构建它,在每个步骤都有一个不同的对象,例如,我可以打印到控制台,而不是一个在一行中创建整个事物的大声明。我已经多次阅读了6月发布的CTP所附的所有文档,正如我所提到的,我在各种构造函数和方法的看似无穷无尽的组合中迷失了。此外,我也对将性能考虑在内的方式感兴趣。
答案 0 :(得分:5)
按照你的建议,我会像下面的代码那样编写一些零碎的东西。我还鼓励您查看一下ImplementINotifyPropertyChanged示例,因为它可以很好地完成语法构造和重写。请注意,正如您所建议的那样,您可以通过多种方式执行此操作。这是因为API旨在支持编辑器等场景,因此您可以通过对用户键入的每次击键应用文本更改来构建它。哪种API是正确的,取决于您要实现的目标。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
using Roslyn.Services;
using Roslyn.Services.CSharp;
class Program
{
static void Main(string[] args)
{
// Create the solution with an empty document
ProjectId projectId;
DocumentId documentId;
var solution = Solution.Create(SolutionId.CreateNewId())
.AddProject("MyProject", "MyProject", LanguageNames.CSharp, out projectId)
.AddDocument(projectId, @"C:\file.cs", string.Empty, out documentId);
var document = solution.GetDocument(documentId);
var root = (CompilationUnitSyntax)document.GetSyntaxRoot();
// Add the namespace
var namespaceAnnotation = new SyntaxAnnotation();
root = root.WithMembers(
Syntax.NamespaceDeclaration(
Syntax.ParseName("MyNamespace"))
.NormalizeWhitespace()
.WithAdditionalAnnotations(namespaceAnnotation));
document = document.UpdateSyntaxRoot(root);
Console.WriteLine("-------------------");
Console.WriteLine("With Namespace");
Console.WriteLine(document.GetText().GetText());
// Find our namespace, add a class to it, and update the document
var namespaceNode = (NamespaceDeclarationSyntax)root
.GetAnnotatedNodesAndTokens(namespaceAnnotation)
.Single()
.AsNode();
var classAnnotation = new SyntaxAnnotation();
var newNamespaceNode = namespaceNode
.WithMembers(
Syntax.List<MemberDeclarationSyntax>(
Syntax.ClassDeclaration("MyClass")
.WithAdditionalAnnotations(classAnnotation)));
root = root.ReplaceNode(namespaceNode, newNamespaceNode).NormalizeWhitespace();
document = document.UpdateSyntaxRoot(root);
Console.WriteLine("-------------------");
Console.WriteLine("With Class");
Console.WriteLine(document.GetText().GetText());
// Find the class, add a method to it and update the document
var classNode = (ClassDeclarationSyntax)root
.GetAnnotatedNodesAndTokens(classAnnotation)
.Single()
.AsNode();
var newClassNode = classNode
.WithMembers(
Syntax.List<MemberDeclarationSyntax>(
Syntax.MethodDeclaration(
Syntax.ParseTypeName("void"),
"MyMethod")
.WithBody(
Syntax.Block())));
root = root.ReplaceNode(classNode, newClassNode).NormalizeWhitespace();
document = document.UpdateSyntaxRoot(root);
Console.WriteLine("-------------------");
Console.WriteLine("With Method");
Console.WriteLine(document.GetText().GetText());
}
}