开发者

How to get complex enum value string representation

Let's say I have this enum:

[Flags]
public enum SomeType
{    
    Val1 = 0,
    Val2 = 1,
    Val3 = 2,
    Val4 = 4,
    Val5 = 8,
    Val6 = 16,
    All = Val1 | Val2 | Val3 | Val4 | Val5 | Val6
}

and some variables:

SomeTyp开发者_如何学JAVAe easyType = SomeType.Val1 | SomeType.Val2;
SomeType complexType = SomeType.All;

If I want to loop through values of the first enum I can simply do:

foreach(string s in easyType.ToString().Split(','))
{ ... }

However, when I try to apply the same approach to the 'complexType' I get value 'All', which is of course valid because it's also one of possible values of the enum. But, is there a neat way to actually see of what values is the SomeType.All created of? I know I could make a manual loop through all the values like that:

if(complexType.HasFlag(ManualType.Val1) && ...


var result = string.Join(",",
                 Enum.GetValues(typeof(SomeType))
                     .Cast<SomeType>()
                     .Where(v => complexType.HasFlag(v)));

You can write an extension method to avoid repeating yourself.


Maybe you need to enumerate the enum values and test each one:

foreach (SomeType item in Enum.GetValues (typeof (SomeType))
{
  if ((complexType & item) == item)
  {
    //...
  }
}


Here's one possible way to do it, building on Danny Chen's answer:

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

Usage:

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

Note this will work for Enums based on types castable to int. You can create similar methods for long etc.


If you're using an enum to represent data that has some deeper level of complexity (arbitrary groups of elements, "darkness" of colour, etc.) and struggling because of that, I'd suggest that an enum is the wrong programming construct to be using.

Using an enum for these tasks will always be error prone: if I add a new colour to your enum, I have to remember to add it to "Bright" or "Dark" too. That makes your code just as error prone for developers as the original problem. What you could do, however, is define a class or struct for colour that has a property indicating whether it's bright or not. Then you'll have clear, understandable functionality - implemented in a way that doesn't give spurious results as when you're trying to misuse a simpler language feature.

That, for example, is why Color is a struct...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜