如何获得复杂的枚举值字符串表示

时间:2011-02-11 11:57:09

标签: c# enums flags

让我说我有这个枚举:

[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) && ...

4 个答案:

答案 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”中。这使得开发人员的代码与原始问题一样容易出错。但是,你可以做的是为classstruct定义颜色,该颜色具有指示它是否亮的属性。然后你将拥有清晰,易懂的功能 - 以一种不会产生虚假结果的方式实现,就像你试图滥用更简单的语言功能一样。

例如,这就是Color is a struct ...

的原因