Alan2
Alan2

Reputation: 24602

Is there a way to enumare through an Enum to construct an array?

I have this code that line by line creates an array:

vm.CardChoice = new[] {
        new ParamViewModel { Id = 0,  Name = CC.JLPT5.Text() },
        new ParamViewModel { Id = 1,  Name = CC.JLPT4.Text() },
        new ParamViewModel { Id = 2,  Name = CC.JLPT3.Text() },
        new ParamViewModel { Id = 3,  Name = CC.JLPT2.Text() },
        new ParamViewModel { Id = 4,  Name = CC.JLPT1.Text() },
        new ParamViewModel { Id = 5,  Name = CC.JFBP1.Text() },
        new ParamViewModel { Id = 5,  Name = CC.JFBP2.Text() },
        new ParamViewModel { Id = 7,  Name = CC.JFBP3.Text() },
        new ParamViewModel { Id = 8,  Name = CC.All.Text()   },
        new ParamViewModel { Id = 9,  Name = CC.Catg.Text()  },
        new ParamViewModel { Id = 10, Name = CC.Cat.Text()   },
        new ParamViewModel { Id = 11, Name = CC.C1.Text()    },
        new ParamViewModel { Id = 12, Name = CC.C2.Text()    },
        new ParamViewModel { Id = 13, Name = CC.C3.Text()    },
        };

Is there any way that I could do this based on the ENUM itself or is the only way to code it line by line? Here's the ENUM that I have:

using System;
namespace Japanese.Enums
{
    public enum CC
    {
        JLPT5 = 0,
        JLPT4 = 1,
        JLPT3 = 2,
        JLPT2 = 3,
        JLPT1 = 4,
        JFBP1 = 5,
        JFBP2 = 6,
        JFBP3 = 7,
        All = 8,
        Catg = 9,
        Cat = 10,
        C1 = 11,
        C2 = 12,
        C3 = 13
    }

    public static partial class Extensions
    {
        public static string Text(this CC cardChoice)
        {
            switch (cardChoice)
            {
                case CC.JLPT5: return "N5";
                case CC.JLPT4: return "N4";
                case CC.JLPT3: return "N3";
                case CC.JLPT2: return "N2";
                case CC.JLPT1: return "N1";
                case CC.JFBP1: return "JFBP1";
                case CC.JFBP2: return "JFBP2";
                case CC.JFBP3: return "JFBP3";
                case CC.All: return "ALL";
                case CC.Catg: return "GROUP";
                case CC.Cat: return "> GROUP";
                case CC.C1: return "C1";
                case CC.C2: return "C2";
                case CC.C3: return "C4";
            }
            return "";
        }

        public static string LongText(this CC cardChoice)
        {
            switch (cardChoice)
            {
                case CC.JLPT5: return "Japanese Language Proficiency Test Level N5";
                case CC.JLPT4: return "Japanese Language Proficiency Test Level N4";
                case CC.JLPT3: return "Japanese Language Proficiency Test Level N3";
                case CC.JLPT2: return "Japanese Language Proficiency Test Level N2";
                case CC.JLPT1: return "Japanese Language Proficiency Test Level N1";
                case CC.JFBP1: return "Japanese for Busy People 1";
                case CC.JFBP2: return "Japanese for Busy People 2";
                case CC.JFBP3: return "Japanese for Busy People 3";
                case CC.All: return "All Available Words";
                case CC.Catg: return "High Level Group";
                case CC.Cat: return "Low Level Group";
                case CC.C1: return "Custom 1";
                case CC.C2: return "Custom 2";
                case CC.C3: return "Custom 3";

            }
            return "";
        }
    }
}

Upvotes: 0

Views: 109

Answers (2)

quetzalcoatl
quetzalcoatl

Reputation: 33596

Check out the System.Enum class. It has a lot of helpful methods like GetNames or GetValues which allow you to read all entries of an enum type. Paired with some LINQ it's really simple to process them semi-automatically.

Once you have a list of enum entries, you can then simply cast them to int to get the numeric value, or you can use Enum.GetName or .ToString to get their names.

You may also want to check this article for some non-LINQ hints what you can do with System.Enum.xxx methods.

https://blogs.msdn.microsoft.com/haibo_luo/2005/08/28/get-names-and-values-of-enum-members/

However, this will only help you in extracting data that directly describes an enum type. That means CC.JLPT3 -> (int)2 or CC.JLPT3 -> (string)"JLPT3". Just this, because the definition of an enum holds only this kind of data and there's nothing more in the enum that could be read..

There is no out-of-the-box magic that would automatically translate that

CC.JLPT3 is a string "N3"

or that

CC.JLPT3 is a string "Japanese Language Proficiency Test Level N3"

These are custom presentational data and completely unrelated to the enum itself.

To get some kind of magic that would simplify managing them, probably the best would be to put that into a dictionary for ease of read/use/update.. Or attributes on the enum, for reuse and ease of coding:

public enum CC
{
    [ShortText("N5")]
    [LongText("Japanese Language Proficiency Test Level N5")]
    JLPT5 = 0,

    [ShortText("N4")]
    [LongText("Japanese Language Proficiency Test Level N4")]
    JLPT4 = 1,

    [ShortText("N3")]
    [LongText("Japanese Language Proficiency Test Level N3")]
    JLPT3 = 2,
    ...

However, as cool as it looks like, there's no such thing out of the box, and you would have to:

  • implement attribute ShortTextAttribute yourself (easy)
  • implement attribute LongTextAttribute yourself (easy)
  • implement utility helper class that would take a CC value and read its long/short attribute to return the text (medium, but internet has ready-to-use samples)

I'm not sure if that's worth the effort, but for sure it would be good excercise.

Upvotes: 1

gmn
gmn

Reputation: 4319

Enum.GetValues()

is what you need:

Enum.GetValues(typeof(CC)).Cast<CC>().Select(x => new ParamViewModel{ Id = (int)x, Name = x.Text()});

Upvotes: 3

Related Questions