我想使用以下类作为具体示例逐步构建一个新的 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、各种 Syntax 对象、ParseCompilationUnit 上的方法等。
基本上,我想以增量方式构建它,在每一步都有一个不同的对象,例如我可以将其打印到控制台,而不是在一行中创建整个事情的一个大语句。我已经多次阅读了 6 月发布的 CTP 附带的所有文档,正如我所提到的,我迷失在各种构造函数和方法看似无穷无尽的组合中。另外,我对一种考虑性能的方式也很感兴趣。
为了按照您的建议逐步构建所有内容,我会编写类似下面的代码的内容。我还鼓励您查看 ImplementINotifyPropertyChanged 示例,因为它进行了大量的语法构造和重写。请注意,正如您所建议的,您可以通过多种方式来执行此操作。这是因为该 API 旨在支持编辑器等场景,因此您也可以通过对用户键入的每次击键应用文本更改来构建此 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());
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)