次のようなコードで定義された複数のフラグ列挙型があります
[Flags]
public enum Colors
{
None = 0,
Red = 1,
Green = 2,
Blue = 4,
Purple = Red | Blue,
Brown = Red | Green,
}
次のコードは、次の出力を生成します
Colors color1 = Colors.Red | Colors.Blue;
Colors color2 = Colors.Purple;
string s1 = color1.ToString(); // Sets s1 to "Purple"
string s2 = color2.ToString(); // Sets s2 to "Purple"
一致する組み合わせが定義されている場合でも、ビットごとの列挙型の個々のビットを出力するメソッドが必要です。
private void Foo()
{
Colors color1 = Colors.Red | Colors.Blue;
Colors color2 = Colors.Purple;
string s1 = CreateColumnString(color1); // Sets s1 to "Red|Blue"
string s2 = CreateColumnString(color2); // Sets s2 to "Red|Blue"
}
列挙型のすべての値をループして、値が 2 のべき乗であるかどうかを確認できると思いました。しかし、Enum 引数の基になる値を取得する方法がわかりません。
private string CreateColumnString(object value)
{
//is this an enum with Flags attribute?
if (value is Enum && value.GetType().GetCustomAttributes(typeof(FlagsAttribute), true).Length > 0)
{
Enum e = (Enum)value;
//Get a list of Enum values set in this flags enum
IEnumerable<Enum> setValues =
Enum.GetValues(value.GetType())
.Cast<Enum>()
.Where(eachEnum => IsPowerOfTwo(eachEnum) && value.HasFlag(eachEnum));
return string.Join("|", setValues);
}
else
{
return value != null ? value.ToString() : string.Empty;
}
return str;
}
private static bool IsPowerOfTwo(Enum e)
{
int x = (int)e; //ERROR cannot convert type 'System.Enum' to 'ulong'
return (x != 0) && ((x & (x - 1)) == 0);
}