Frage

So, I feel like it's possible, but i don't have the chops to put it together. I have lookup tables (with ID and Name fields). I have enums that I keep in sync with the lookups. What I'd like is to make a list of SQL tables, and have roslyn create the enums during/before compile. this way I know my enums are always in sync, and it's one more thing off my plate.

Could someone out there show me the way, or tell me why it would be a bad idea? I feel like the solution isn't really a lot of code...

Thanks!

War es hilfreich?

Lösung

This is how you create enums with roslyn;

class Program
{
    static void Main(string[] args)
    {
        var member1 = Syntax.EnumMemberDeclaration(
            identifier: Syntax.Identifier("Member1")
            );

        var declaration = Syntax.EnumDeclaration(
            identifier: Syntax.Identifier("MyEnum"),
            modifiers: Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword)),
            members: Syntax.SeparatedList(member1)
            );

        Console.WriteLine(declaration.Format());
        Console.ReadLine();
    }
}

this returns:

public enum MyEnum
{
    Member1
}

Now to your question, I don't know if this is what you really need.

First I think there is not yet any built in functionality to do this at precompile, so you'd need to create a console exe and call it in your prebuild events.

So at this point probably it is a better idea to do this manually via code generation and not on every build, unless these tables are changing very frequently.

An in this case you don't really need roslyn to do it for you, you can just spit it out with any code generation software, or roll your own...

Andere Tipps

Here is some code updated for the current version of Roslyn and also shows adding attributes and values to the enum items.

        public EnumDeclarationSyntax GenerateEnum()
    {
        var loanPurpose = new[]
        {
            "Business Launching",
            "HomePurchase",
            "HomeImprovement"

        };
        var enumDescriptions = new[]
        {
            "Launch a new business",
            "Buy a home",
            "Make home improvements"
        };
        var i = 0;
        var members = new List<EnumMemberDeclarationSyntax>();
        foreach (var item in loanPurpose)
        {
            var attribute = SyntaxFactory.Attribute(
                SyntaxFactory.IdentifierName("Description"));
            var attributeArgument = SyntaxFactory.AttributeArgument(
                SyntaxFactory.LiteralExpression(
                    SyntaxKind.StringLiteralExpression,
                    SyntaxFactory.Literal(enumDescriptions[i ])));
            attribute = attribute.WithArgumentList(
                SyntaxFactory.AttributeArgumentList(
                    SyntaxFactory.SingletonSeparatedList(attributeArgument)));
            var attributes = SyntaxFactory.SingletonList(
                SyntaxFactory.AttributeList(SyntaxFactory
                    .SingletonSeparatedList(attribute)));
            var objectCreationExpression = SyntaxFactory.EqualsValueClause(
                SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                    SyntaxFactory.Literal(i)));
            var member = SyntaxFactory.EnumMemberDeclaration(attributes, 
                SyntaxFactory.Identifier(item),
                objectCreationExpression);
            members.Add(member);
            i++;
        }
        var declaration = SyntaxFactory.EnumDeclaration
            (new SyntaxList<AttributeListSyntax>(),
            baseList: null,
            identifier: SyntaxFactory.Identifier("LoanPurpose"),
            modifiers: SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)),
            members: SyntaxFactory.SeparatedList(members)
            );
        return declaration;
    }

The syntax for adding the attributes gets a little awkward but I find that I often need some attributes added. You probably already have the data for the attributes and values in the lookup tables driving the code generation.

The Answer provided by Sebastian 6 years ago likely used to work but no longer does. New set of sample code to accomplish the same thing as of 18/12/2017

EnumMemberDeclarationSyntax member1 = EnumMemberDeclaration(identifier: Identifier("Member1"));

var members =new SyntaxNodeOrToken[]{member1};

var declaration = EnumDeclaration(
            identifier: Identifier("MyEnum")).WithMembers(
            members: SeparatedList< EnumMemberDeclarationSyntax>(members));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top