如何对枚举值进行分组?
假设我有一个像
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类。但我想在没有额外课程的情况下这样做,因为当我需要这个功能时,我可以忘记相关的课程。
答案 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());