У меня есть перечисление, например ' Gender
' ( Male =0 , Female =1
), и у меня есть другое перечисление из службы, у которой есть собственное перечисление Gender ( Male =0 , Female =1, Unknown =2
)
Мой вопрос в том, как я могу написать что-то быстрое и красивое, чтобы преобразовать их перечисление в мое?
Ответы:
Использование метода расширения работает довольно аккуратно при использовании двух методов преобразования, предложенных Нейтом:
Очевидно, что нет необходимости использовать отдельные классы, если вы этого не хотите. Я предпочитаю, чтобы методы расширения были сгруппированы по классам / структурам / перечислениям, к которым они применяются.
источник
Учитывая
Enum1 value = ...
, то, если вы имеете в виду по имени:Если вы имеете в виду числовое значение, вы обычно можете просто привести:
(с приведением вы можете использовать
Enum.IsDefined
для проверки допустимых значений)источник
Enum.Tryparse
:Enum2 value2 = Enum.TryParse(value.ToString(), out Enum2 outValue) ? outValue : Enum2.Unknown;
Это позволит вам обрабатывать входные значения, которые не существуют,Enum2
без необходимости вызыватьEnum.IsDefined
или перехватыватьArgumentException
выброшенныеEnum.Parse
. Обратите внимание, что порядок параметров более или менее обратныйEnum.Parse
.Просто приведите один к int, а затем приведите его к другому перечислению (учитывая, что вы хотите, чтобы отображение выполнялось на основе значения):
источник
long
(илиulong
), а не, дляint
которого определены члены, которые находятся вышеint.MaxValue
(или нижеint.MinValue
), и в этом случае приведение кint
может переполниться, и вы получите неопределенное значение перечисления, которое должно быть определено.Чтобы быть внимательным, я обычно создаю пару функций, одна из которых принимает Enum 1 и возвращает Enum 2, а другая принимает Enum 2 и возвращает Enum 1. Каждая из них состоит из оператора case, отображающего входы и выходы, а case по умолчанию генерирует исключение с сообщение с жалобой на неожиданное значение.
В этом конкретном случае вы могли бы воспользоваться тем фактом, что целочисленные значения Male и Female одинаковы, но я бы избегал этого, поскольку это хакерский и может быть поврежден, если одно из перечислений изменится в будущем.
источник
Если у нас есть:
и
Мы можем безопасно делать
Или даже
Если вы хотите охватить случай, когда перечисление справа от знака '=' имеет больше значений, чем перечисление слева, вам придется написать свой собственный метод / словарь, чтобы охватить это, как предлагали другие.
источник
Вы можете написать простой универсальный метод расширения, подобный этому
источник
вы можете написать простую функцию, подобную следующей:
источник
Вот версия метода расширения, если кому интересно
источник
источник
Некоторое время назад я написал набор методов расширения, которые работают для нескольких различных типов
Enum
s. Один, в частности, работает для того, что вы пытаетесь выполнить, и обрабатываетEnum
sFlagsAttribute
какEnum
с, так и с различными базовыми типами.Оттуда вы можете добавить другие более конкретные методы расширения.
Это изменит типы
Enum
s, как вы пытаетесь это сделать.Однако имейте в виду, что вы МОЖЕТЕ конвертировать между любым
Enum
и любым другим,Enum
используя этот метод, даже теми, у которых нет флагов. Например:Переменная
turtle
будет иметь значениеTurtle.Blue
.Однако
Enum
при использовании этого метода есть безопасность от неопределенных значений. Например:В этом случае
access
будет установлено значениеWriteAccess.ReadWrite
, посколькуWriteAccess
Enum
максимальное значение параметра равно 3.Еще один побочный эффект от смешивания
Enum
s сFlagsAttribute
и без него заключается в том, что процесс преобразования не приведет к совпадению 1 к 1 между их значениями.В этом случае
letters
будет иметь значениеLetters.H
вместо вместоLetters.D
, поскольку резервное значениеFlavors.Peach
равно 8. Кроме того, преобразование изFlavors.Cherry | Flavors.Grape
вLetters
может дать результатLetters.C
, что может показаться неинтуитивным.источник
Основываясь на ответе Джастина выше, я пришел к следующему:
источник
Я знаю, что это старый вопрос и на него есть много ответов, однако я считаю, что использование оператора switch, как в принятом ответе, несколько громоздко, поэтому вот мои 2 цента:
Мой личный любимый метод - использовать словарь, где ключ - это исходное перечисление, а значение - целевое перечисление, поэтому в случае, представленном в вопросе, мой код будет выглядеть так:
Конечно, это можно обернуть в статический класс и использовать как методы расширения:
источник
Вы можете использовать ToString () для преобразования первого перечисления в его имя, а затем Enum.Parse () для преобразования строки обратно в другое Enum. Это вызовет исключение, если значение не поддерживается перечислением назначения (например, для значения «Неизвестно»).
источник