Domanda

I am trying to convert a IEnumerable<object[]> property

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) };
    }
}

to a object[] field

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) },
};

Here is my attempt:

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());

This implementation produces

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) },
 };

The formatting is quite off. The newobject[] is one word instead of new object[]. Actually it's not needed at all, but I couldn't figure out how to create the initializer statement without it.

My questions are:
1. Is there any way to do a quick formatting?
2. Is there a better way to do this. Trying to get all the details perfect seems to be time consuming.

È stato utile?

Soluzione

  1. To create an array with an implicit type use an ImplicitArrayCreationExpression instead of an ArrayCreationExpression:

    var initializerNode = SyntaxFactory
        .ImplicitArrayCreationExpression(SyntaxFactory
            .InitializerExpression(SyntaxKind.ArrayInitializerExpression)
            .WithExpressions(SyntaxFactory.SeparatedList(testCases, seperators)));
    
  2. You can format your freshly created syntax using the Formatter. Say you've assigned the returned results of your implementation to the variable result, then you can call it like this:

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

    Which produces this nicely formatted output for your example (I've hardcoded the name 'after'):

    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. You should try the Roslyn Syntax Visualizer Tool (View > Other Windows > Roslyn Syntax Visualizer). It allows you to look at what syntax nodes Roslyn creates for a given piece of code in your current document. This usually helps a lot when you're trying to figure out how to properly construct your own trees!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top