Ответ 1
Если я правильно понял, что вы спросили, это должно сработать для вас:
Enum.GetValues(typeof(Enum)).Cast<int>().Sum();
У меня есть перечисление с атрибутом 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);
Вид грубого, но что-то вроде этого?
[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);
}
Вот способ сделать это, используя идеи от общие операторы, написанные Джоном Скитом и Марком Гравелем:
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);
}
}
Этот код динамически создает делегат, который объединяет значения enum с оператором OR