如何在保留琐事的同时替换节点?

时间:2014-05-02 22:41:12

标签: c# roslyn

我正在尝试转换IEnumerable<object[]>属性

public IEnumerable<object[]> BeforeConversion
{
    get
    {
        yield return new object[] { new DateTime(2013, 8, 23), new DateTime(2013, 09, 15) };
        yield return new object[] { new DateTime(2013, 9, 20), new DateTime(2013, 10, 15) };
    }
}

object[]字段

static object[] AfterConversion =
{
    new object[] { new DateTime(2013, 8, 23), new DateTime(2013, 09, 15) },
    new object[] { new DateTime(2013, 9, 20), new DateTime(2013, 10, 15) },
};

这是我的尝试:

var testCases = node.DescendantNodes((_) => true).OfType<ArrayCreationExpressionSyntax>()
                    .Select(i => ((ExpressionSyntax)i))
                    .ToArray();                    

var arrayType = node.DescendantNodes((_) => true).OfType<ArrayTypeSyntax>().First();

var seperators = Enumerable.Repeat(SyntaxFactory
    .Token(SyntaxKind.CommaToken)
    .WithTrailingTrivia(LineFeed), testCases.Length);
var initializerNode = SyntaxFactory       
    .ArrayCreationExpression(arrayType)
    .WithInitializer(SyntaxFactory
        .InitializerExpression(SyntaxKind.ArrayInitializerExpression)
        .WithExpressions(SyntaxFactory.SeparatedList(testCases, seperators)));

return SyntaxFactory.FieldDeclaration(
    new SyntaxList<AttributeListSyntax>(),
    SyntaxFactory.TokenList().Add(
        SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithTrailingTrivia(Space)),
    SyntaxFactory.VariableDeclaration(arrayType.WithTrailingTrivia(Space),
        SyntaxFactory.SeparatedList<VariableDeclaratorSyntax>().Add(
            SyntaxFactory.VariableDeclarator(newName).WithInitializer(
            SyntaxFactory.EqualsValueClause(
                SyntaxFactory.Token(SyntaxKind.EqualsToken).WithLeadingTrivia(Space),
                initializerNode)))))
    .WithLeadingTrivia(node.GetLeadingTrivia())
    .WithTrailingTrivia(node.GetTrailingTrivia());

此实现产生

static object[] TestGetExpirationDateCases =newobject[]{new object[] { new DateTime(2013, 8, 23), new DateTime(2013, 09, 15) },
 new object[] { new DateTime(2013, 9, 20), new DateTime(2013, 10, 15) },
 };

格式化很完整。 newobject []是一个单词而不是new object []。实际上它根本不需要,但我无法弄清楚如何在没有它的情况下创建初始化语句。

我的问题是:
 1.有没有办法快速格式化?
 2.有没有更好的方法来做到这一点。试图让所有细节变得完美似乎很费劲。

1 个答案:

答案 0 :(得分:2)

  1. 要创建具有隐式类型的数组,请使用ImplicitArrayCreationExpression而不是ArrayCreationExpression

    var initializerNode = SyntaxFactory
        .ImplicitArrayCreationExpression(SyntaxFactory
            .InitializerExpression(SyntaxKind.ArrayInitializerExpression)
            .WithExpressions(SyntaxFactory.SeparatedList(testCases, seperators)));
    
  2. 您可以使用Formatter格式化新创建的语法。假设您已将实现的返回结果分配给变量result,那么您可以这样调用它:

    using Microsoft.CodeAnalysis.Formatting;
    
    var formattedResult = Formatter.Format(result, workspace);
    

    为您的示例生成这个格式良好的输出(我在'之后'硬编码了名称):

    static object[] after = new[]
    {
        new object[] { new DateTime(2013, 8, 23), new DateTime(2013, 09, 15) },
        new object[] { new DateTime(2013, 9, 20), new DateTime(2013, 10, 15) },
    };
    
  3. 您应该尝试Roslyn Syntax Visualizer Tool(查看&gt;其他Windows&gt; Roslyn语法展示台)。它允许您查看Roslyn为当前文档中的给定代码片段创建的语法节点。当你试图弄清楚如何正确构建你自己的树时,这通常会有很大的帮助!