让我说我有这个枚举:
[Flags]
public enum SomeType
{
Val1 = 0,
Val2 = 1,
Val3 = 2,
Val4 = 4,
Val5 = 8,
Val6 = 16,
All = Val1 | Val2 | Val3 | Val4 | Val5 | Val6
}
和一些变量:
SomeType easyType = SomeType.Val1 | SomeType.Val2;
SomeType complexType = SomeType.All;
如果我想循环第一个枚举的值,我可以这样做:
foreach(string s in easyType.ToString().Split(','))
{ ... }
然而,当我尝试对'complexType'应用相同的方法时,我得到值'All',这当然是有效的,因为它也是枚举的可能值之一。但是,有没有一种巧妙的方法来实际看到SomeType.All创建的值是什么?我知道我可以手动循环遍历所有这些值:
if(complexType.HasFlag(ManualType.Val1) && ...
答案 0 :(得分:4)
var result = string.Join(",",
Enum.GetValues(typeof(SomeType))
.Cast<SomeType>()
.Where(v => complexType.HasFlag(v)));
您可以编写扩展方法以避免重复自己。
答案 1 :(得分:0)
也许您需要枚举枚举值并测试每个值:
foreach (SomeType item in Enum.GetValues (typeof (SomeType))
{
if ((complexType & item) == item)
{
//...
}
}
答案 2 :(得分:0)
这是一种可行的方法,以Danny Chen的答案为基础:
public IEnumerable<T> GetFlags<T>(Predicate<int> hasFlag)
{
return GetEnumFlags<T>().Where(f => hasFlag(f)).Cast<T>();
}
private IEnumerable<int> GetEnumFlags<T>()
{
return Enum.GetValues(typeof(T)).Cast<int>().Where(IsPowerOfTwoOrZero);
}
private bool IsPowerOfTwoOrZero(int v)
{
return ((v & (v-1)) == 0);
}
用法:
void Main()
{
SomeType easyType = SomeType.Val1 | SomeType.Val2;
SomeType complexType = SomeType.All;
GetFlags<SomeType>(v => easyType.HasFlag((SomeType)v));
GetFlags<SomeType>(v => complexType.HasFlag((SomeType)v));
}
请注意,这适用于基于可转换为int
的类型的枚举。您可以为long
等创建类似的方法。
答案 3 :(得分:0)
如果你使用枚举来表示具有更深层次复杂性的数据(任意元素组,颜色的“黑暗”等)并因此而挣扎,我建议枚举是错误的编程构造要使用。
使用enum执行这些任务总是容易出错:如果我为你的枚举添加一个新颜色,我必须记得将它添加到“Bright”或“Dark”中。这使得开发人员的代码与原始问题一样容易出错。但是,你可以做的是为class
或struct
定义颜色,该颜色具有指示它是否亮的属性。然后你将拥有清晰,易懂的功能 - 以一种不会产生虚假结果的方式实现,就像你试图滥用更简单的语言功能一样。
例如,这就是Color
is a struct
...