2

具体的な例として、次のクラスを使用して、新しい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など、あらゆる種類の異なるオブジェクトの無限のメソッドとコンストラクター。

基本的に、これを段階的に構築し、各ステップで個別のオブジェクトを作成して、たとえばコンソールに出力できるようにします。このすべてを1行で作成する1つの大きなステートメントではありません。6月のCTPリリースに付属するすべてのドキュメントを何度か読みましたが、前述したように、さまざまなコンストラクターとメソッドの無限の組み合わせに迷いました。また、パフォーマンスも考慮した方法に興味があります。

4

1 に答える 1

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());
    }
}
于 2012-06-24T05:10:17.313 に答える