Как преобразовать IEnumerable‹Enum› в Enum в C#?

Я разобрал несколько строк в флаги Enum, но не вижу удобного способа объединить их в одно битовое поле Enum.

Метод, который я использую, перебирает строковые значения, а затем |= приводит значения к объекту Enum, например:

[Flags]
public enum MyEnum { None = 0, First = 1, Second = 2, Third = 4 }
...

string[] flags = { "First", "Third" };
MyEnum e = MyEnum.None;

foreach (string flag in flags)
    e |= (MyEnum)Enum.Parse(typeof(MyEnum), flag, true);

Я пытался использовать метод Select для преобразования в мой тип Enum, но затем я застрял с IEnumerable<MyEnum>. Какие-либо предложения?


person waj    schedule 07.08.2011    source источник
comment
Это IEnumerable<string>, а не IEnumerable<Enum>.   -  person BoltClock    schedule 07.08.2011
comment
@BoltClock, в примере кода показан массив строк, но использование flags.select(flag => (MyEnum)Enum.Parse(typeof(MyEnum), flag, true)) действительно возвращает IEnumerable<Enum>, и именно здесь я застрял.   -  person waj    schedule 07.08.2011


Ответы (2)


Ну, из IEnumerable<MyEnum> вы можете использовать:

MyEnum result = parsed.Aggregate((current, next) => current | next);

или для размещения пустой последовательности:

MyEnum result = parsed.Aggregate(MyEnum.None, (current, next) => current | next);

По общему признанию, это в основном то же самое, что и у вас уже есть...

Итак, в целом код будет таким:

MyEnum result = flags.Select(x => (MyEnum) Enum.Parse(typeof(MyEnum), x))
                     .Aggregate(MyEnum.None, (current, next) => current | next);

(Вы можете выполнить это за один вызов Aggregate в соответствии с ответом Гуффы, но лично я думаю, что для ясности я бы разделил их на два. Однако это личное предпочтение.)

Обратите внимание, что мой проект Unconstrained Melody/">Unconstrained Melody делает обработку перечислений несколько более приятной, и вы также можете использовать общий Enum.TryParse в .NET 4.

Так, например, используя Unconstrained Melody, вы можете использовать:

MyEnum result = flags.Select(x => Enums.ParseName<MyEnum>(x))
                     .Aggregate(MyEnum.None, (current, next) => current | next);
person Jon Skeet    schedule 07.08.2011

Вы можете использовать метод Aggregate для объединения флагов:

MyEnum e = flags
  .Select(s => (MyEnum)Enum.Parse(typeof(MyEnum), s, true))
  .Aggregate(MyEnum.None, (f, n) => f | n);
person Guffa    schedule 07.08.2011