我有一个Flags属性的枚举。获得枚举标志所有位的最佳方法?
我的问题是,我想获得所有选项的整数位掩码,而无需手动合并所有位。 我想这样做来比较一些其他的int领域,我想保护以防万一未来的开发人员更多的位选项的枚举。
另一件事是在我的枚举标志位将所有手动分配的,所以我不能简单地得到下一个值和减去1
我有一个Flags属性的枚举。获得枚举标志所有位的最佳方法?
我的问题是,我想获得所有选项的整数位掩码,而无需手动合并所有位。 我想这样做来比较一些其他的int领域,我想保护以防万一未来的开发人员更多的位选项的枚举。
另一件事是在我的枚举标志位将所有手动分配的,所以我不能简单地得到下一个值和减去1
如果我明白你的要求正确这应该为你工作:
Enum.GetValues(typeof(Enum)).Cast<int>().Sum();
看一看我的Unconstrained Melody项目,该项目确实邪恶的东西,让漂亮的功能将建立在约束枚举和委托的通用方法上。
在这种情况下,我想你想打电话给Flags.GetUsedBits<YourEnumType>()
。
如果你不介意使用额外的(非常小的)库,我想认为Unconstrained Melody在处理标志时会使生活更美好。如果您有任何功能请求,我很乐意看看:)
// uses a ulong to handle all possible underlying types without error
var allFlags = Enum.GetValues(typeof(YourEnumType))
.Cast<YourEnumType>()
.Aggregate((YourEnumType)0, (a, x) => a | x, a => (ulong)a);
我不能+1这个,因为它是如此接近我在输入“答案添加”消息时出现的内容。它在长枚举上失败,因此可能将Cast转换为Cast
@Jon:固定。现在将聚合值输入为“ulong”,以便它可以处理所有可能的基础类型。 (我已经投了它,而不是把它作为'YourEnumType',因为OP要求一个* integer *位掩码。) – LukeH 2010-08-11 22:41:41
这里有一个办法做到这一点,使用的想法从乔恩斯基特和Marc Gravell写的generic operators:
void Main()
{
Console.WriteLine(CombineAllFlags<MyEnum>()); // Prints "Foo, Bar, Baz"
}
[Flags]
public enum MyEnum
{
Foo = 1,
Bar = 2,
Baz = 4
}
public static TEnum CombineAllFlags<TEnum>()
{
TEnum[] values = (TEnum[])Enum.GetValues(typeof(TEnum));
TEnum tmp = default(TEnum);
foreach (TEnum v in values)
{
tmp = EnumHelper<TEnum>.Or(tmp, v);
}
return tmp;
}
static class EnumHelper<T>
{
private static Func<T, T, T> _orOperator = MakeOrOperator();
private static Func<T, T, T> MakeOrOperator()
{
Type underlyingType = Enum.GetUnderlyingType(typeof(T));
ParameterExpression xParam = Expression.Parameter(typeof(T), "x");
ParameterExpression yParam = Expression.Parameter(typeof(T), "y");
var expr =
Expression.Lambda<Func<T, T, T>>(
Expression.Convert(
Expression.Or(
Expression.Convert(xParam, underlyingType),
Expression.Convert(yParam, underlyingType)),
typeof(T)),
xParam,
yParam);
return expr.Compile();
}
public static T Or(T x, T y)
{
return _orOperator(x, y);
}
}
此代码动态创建,结合枚举值与作业者的委托
类似的原油,但类似的东西?
[Flags]
enum SomeFlags
{
Flag1 = 1,
Flag2 = 2,
Flag3 = 4,
Flag4 = 16,
Flag5 = 32,
Flag6 = 64
}
static void Main(string[] args)
{
SomeFlags flags = 0;
SomeFlags[] values = (SomeFlags[])Enum.GetValues(typeof(SomeFlags));
Array.ForEach<SomeFlags>(values, delegate(SomeFlags v) { flags |= v; });
int bitMask = Convert.ToInt32(flags);
}
+1,很干净。 – 2010-08-11 22:00:33
只有在定义类型中不存在重复时才有效,这通常与同义词或预先组合的常见组合有关。 – 2010-08-11 22:03:39
这绝对是最干净的解决方案,你也可以直接得到返回的数组,并执行任何其他想要的操作,如ORing而不是求和。 – Winforms 2010-08-11 22:05:06