如何分组枚举值?

时间:2012-02-15 18:39:46

标签: c#

如何对枚举值进行分组?
假设我有一个像

这样的枚举
public enum Colors
  {
    LightBlue,
    LightGreen,
    DarkGreen,
    Black,
    White,
    LightGry,
    Yellow
  }

现在我想定义一些颜色组,例如浅色(LightBlue,LightGreen,White,LightGray,Yellow)和深色(Black,DarkGreen)。
所以我可以在我的代码中询问不同地方的小组 如果我没记错我的Java时间,我可以在Java中为枚举添加方法。我认为这在C#中是不可能的。但也许还有其他方法。

Edit1:当然我可以添加一个带有IsADarkColor(Colors c)等静态成员的Utility类。但我想在没有额外课程的情况下这样做,因为当我需要这个功能时,我可以忘记相关的课程。

7 个答案:

答案 0 :(得分:11)

  

我可以添加一个包含IsADarkColor(Colors c)等静态成员的Utility类。但我想在没有额外课程的情况下这样做,因为当我需要这个功能时,我可以忘记相关的课程。

这是扩展方法派上用场的时候:

// 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;
        }
    }
}

只要这两个类在同一个命名空间中,就可以看到静态方法,就好像它属于Color类一样:

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

(给@Abdul提示让我想到扩展方法)

答案 1 :(得分:5)

你需要在课堂上写这个。

就个人而言,我建议将其重新编写为Color(单数)枚举和Colors类。然后,Colors类可以包含返回枚举“组”的方法或属性(即:IEnumerable<Color> LightColors { get { //...

答案 2 :(得分:2)

像这样的简单分组可以通过Flags和一些按位数学进行管理。

    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ánielSzabó)/复数视线

答案 3 :(得分:1)

没有枚举的子分组,但是在某些情况下,您可以使用按位运算在某种程度上实现这一点。 (参见this post获得适当的解释)

我会坚持使用实用程序类,说实话,它没有任何混乱,这意味着你可以随着网站的增长添加其他描述,下拉操作等。

答案 4 :(得分:1)

我认为最简单的方法是指定一个范围内的值。例如:

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

然后,100以上的所有值都应该是深色。您甚至可以为此目的添加扩展方法

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

并像这样使用它:

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

答案 5 :(得分:0)

在C#中你可以这样做(我不确定,你真的想要这个或不)

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

}

答案 6 :(得分:0)

您可以使用反射。
首先,您必须标记您的类别:

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

然后,您应该创建一些辅助类/扩展方法以获取该信息:

 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;
    }

最后,您可以使用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());