[ACCEPTED]-How to group Enum values?-c#

Accepted answer
Score: 14

I can add a Utility class with static member 8 like IsADarkColor(Colors c). But I would like do it without an 7 additional class because I could forget 6 that related class when I need that feature.

This 5 is when Extension Methods come in handy:

// Taking Reed Copsey's naming advice
public enum Color
{
    LightBlue,
    LightGreen,
    DarkGreen,
    Black,
    White,
    LightGray,
    Yellow
}

public static class Colors
{
    public static bool IsLightColor(this Color color)
    {
        switch(color){
            case Color.LightBlue:
            case Color.LightGreen:
            case Color.DarkGreen:
            case Color.LightGray:
            return true;
            default: 
            return false;
        }
    }
}

As long as these 4 two classes are in the same namespace, you 3 can see the static method as if it belonged 2 to the Color class:

var color = Color.LightBlue;
if(color.IsLightColor()) {...}

(hat tip to @Abdul for 1 making me think of extension methods)

Score: 6

You will need to write this in a class.

Personally, I 4 would recommend reworking this into a Color (singular) enum, and 3 a Colors class. The Colors class could then include 2 methods or properties which return "groups" of 1 enums (ie: IEnumerable<Color> LightColors { get { //...)

Score: 2

You may use reflection.
First you have 4 to mark your categories:

public enum Colors
{
    [Category("LightColor")]
    LightBlue,
    [Category("LightColor")]
    LightGreen,
    [Category("DarkColor")]
    DarkGreen,
    [Category("DarkColor")]
    Black,
    [Category("LightColor")]
    White,
    [Category("LightColor")]
    LightGry,
    [Category("LightColor")]
    Yellow
}

Then you should 3 create some helper class/extension method 2 in order to fetch that information:

 public static string GetCategory(this Colors source)
    {
        FieldInfo fieldInfo = source.GetType().GetField(source.ToString());

        CategoryAttribute attribute = (CategoryAttribute)fieldInfo.GetCustomAttribute(typeof(CategoryAttribute), false);

        return attribute.Category;
    }

Finally 1 you can do whatever you what with LINQ:

 var permissions = Enum.GetValues(typeof(Colors)).Cast<Colors>()
            .Select(x => new { Category = x.GetCategory(), Value = x.ToString() })
            .GroupBy(x => x.Category)
            .ToDictionary(grp => grp.Key, grp => grp.Select(x => x.Value).ToList());
Score: 1

There is not sub-grouping of enums, however 7 you can use bitwise operations to achive 6 this to some degree in some cases. (See 5 this post for a decent explanaition)

I would just 4 stick with the utility class to be honest, there's 3 nothing messy about it and it means you 2 can add other descriptions, dropdown operations 1 etc as your site grows.

Score: 1

I think the simplest way would be to specify 4 values within a range. For example:

public enum Color
{
    LightBlue,
    LightGreen,
    LightGray,
    White,
    Yellow,
    DarkGreen = 100,
    Black
}

Then 3 all values above 100 are supposed to be 2 dark colors. You can even add an extension 1 method for that purpose

public bool static IsLightColor(this Color c)
{
    return c < DarkGreen;
}

And use it like this:

 Color c = Color.LightBlue;
 if (c.IsLightColor())
 {
       // do something
 }
Score: 1

Simple groupings like this can be managed 2 with Flags and some bitwise math.

    public class Program
    {
        public static void Main()
        {
            var test = Colors.Red;

            var isWarm = Constants.WarmColors.HasFlag(test);
            var isCool = Constants.CoolColors.HasFlag(test);

            Console.WriteLine(isWarm);  //true
            Console.WriteLine(isCool);  //false
        }

        public static class Constants
        {
            public static Colors CoolColors = Colors.Green | Colors.Blue | Colors.Purple;
            public static Colors WarmColors = Colors.Red | Colors.Orange | Colors.Yellow;
        }

        [Flags]
        public enum Colors
        {
            White = 0,
            Red = 1,
            Orange = 1 << 1,
            Yellow = 1 << 2,
            Green = 1 << 3,
            Blue = 1 << 4,
            Purple = 1 << 5,
            Brown = 1 << 6,
            Black = 1 << 7
        }
    }

Bitwise and shift operators (C# reference) --Microsoft)

Logical and Bitwise Operators in C# -- Dániel 1 Szabó/Plural Sight

Score: 0

in C# you can do it as follows ( i m not 1 sure, you really want this or not)

public enum Colors
  {
    LightBlue,
    LightGreen,
    DarkGreen,
    Black,
    White,
    LightGry,
    Yellow
  }


public enum LightColors{
   LightBlue = Colors.LightBlue, 
   LightGreen = Colors.LightGreen,
   White = Colors.White, 
   LightGray = Colors.LightGray, 
   Yellow = Colors.Yellow
}
public enum DarkColors{
   Black = Colors.Black, 
   DarkGreen = Colors.DarkGreen

}

More Related questions