简体   繁体   中英

Adding class members into specific locations using Roslyn?

I am adding private fields into a class using ClassDeclarationSyntax.AddMembers method. Fields appear in the class, but I'd like to know how to add the fields into specific locations. As of now, they are added at the end of the class inside #if directive that happens to evaluate to true at the time of running the code generation.

Running the code:

var tree = SyntaxTree.ParseCompilationUnit(@"
namespace Test
{
    public class A
    {
#if !SILVERLIGHT
        public int someField;
#endif
    }
}");
var field =
    Syntax.FieldDeclaration(
        Syntax.VariableDeclaration(
            Syntax.PredefinedType(
                Syntax.Token(
                    SyntaxKind.StringKeyword))))
    .WithModifiers(Syntax.Token(SyntaxKind.PrivateKeyword))
    .AddDeclarationVariables(Syntax.VariableDeclarator("myAddedField"));
var theClass = tree.GetRoot().DescendantNodes()
    .OfType<ClassDeclarationSyntax>().First();
theClass = theClass.AddMembers(field).NormalizeWhitespace();
System.Diagnostics.Debug.Write(theClass.GetFullText());

will result in this:

public class A
{
#if !SILVERLIGHT
    public int someField;
    private string myAddedField;
#endif
}

And I would like to get this result:

public class A
{
    private string myAddedField;
#if !SILVERLIGHT
    public int someField;
#endif
}

To do this, you will have to locate where exactly do you want to place the new member and then modify the list of the class members accordingly. Something like:

private static SyntaxList<MemberDeclarationSyntax> AddBeforeIfDirective(
    SyntaxList<MemberDeclarationSyntax> oldMembers,
    MemberDeclarationSyntax newMember)
{
    var ifIndex = oldMembers.IndexOf(
        member => member.GetLeadingTrivia()
            .Any(t => t.Kind == SyntaxKind.IfDirective));
    return oldMembers.Insert(ifIndex, newMember);
}


…

var newMembers = AddBeforeIfDirective(theClass.Members, field);

theClass = theClass.WithMembers(newMembers).NormalizeWhitespace();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM