Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to group Enum values?

Tags:

c#

How can I group Enum values?
Assume I have an enum like

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

Now I want to define some groups of colors, e.g. the light colors (LightBlue, LightGreen, White, LightGray, Yellow) and dark colors (Black, DarkGreen).
So I can ask for groups at different places in my code.
If I remember correctly my Java time I just could add methods to the enums in Java. I think that is not possible in C#. But maybe there are other ways.

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

like image 428
brgerner Avatar asked Feb 15 '12 18:02

brgerner


3 Answers

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

This 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 two classes are in the same namespace, you can see the static method as if it belonged to the Color class:

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

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

like image 144
StriplingWarrior Avatar answered Nov 19 '22 10:11

StriplingWarrior


You will need to write this in a class.

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

like image 24
Reed Copsey Avatar answered Nov 19 '22 09:11

Reed Copsey


You may use reflection.
First you have 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 create some helper class/extension method 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 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());
like image 3
chunk1ty Avatar answered Nov 19 '22 11:11

chunk1ty