私は次のような列挙型を持っています:
enum foo{
a=0,
b=1,
c=2,
d=4
}
フラグ/ビットマスクの作成は問題ありませんが、次のようなことは可能ですか?
int i = 3;
var bar = Enum.Split(foo,i);
次のような結果になります
bar = foo[]{a, b,c};
ありがとう。
次を試してください
public static IEnumerable<T> Split<T>(int value) {
foreach (object cur in Enum.GetValues(typeof(T))) {
var number = (int)(object)(T)cur;
if (0 != (number & value)) {
yield return (T)cur;
}
}
}
これであなたは今書くことができます
int i = 3;
IEnumerable<foo> e = Split<foo>(i);
注:これは、 (デフォルト設定)enum
から派生した値でのみ機能します。int
また、値T
だけに制限することはできないため、完全にタイプセーフではありませんenum
(ただし、それについては何もしません)
列挙型でを使用しFlagsAttribute
て、多くの機能を無料で入手できます(ビットレベルで作業する必要はありません)。
MSDNは、属性を次のように説明しています。
列挙型をビットフィールドとして扱うことができることを示します。つまり、フラグのセットです。
を使用[FlagsAttribute]
すると、すべての有効な値を抽出できます。
http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx
これを試して:
TEnum[] EnumSplit<TEnum>(int mask)
{
List<TEnum> values = new List<TEnum>();
foreach(int enumValue in Enum.GetValues(typeof(TEnum)))
{
if(mask & enumValue == enumValue)
values.Add((TEnum)enumValue);
}
return values.ToArray();
}
このように呼んでください:
var bar = EnumSplit<foo>(i);
IEnumerable<TEnum>
できれば、の代わりに戻るように変更することをお勧めしますTEnum[]
。
Enum
これは、渡した値から値を取得するメソッドを使用して行うことができます。
public static T[] EnumSplit<T>(int value) where T : struct
{
// Simplified as Enum.GetValues will complain if T is not an enum
// However, you should add a check to make sure T implements FlagAttribute
return (from vv in Enum.GetValues(typeof(T))
where ((int)vv & value) != 0
select (T)vv).ToArray();;
}
var flags = Enum.GetValues(typeof (/* YourEnumType */))
.Cast</* YourEnumType */>()
.Select(v => enumValue.HasFlag(v))
.ToArray();