Mam na przykład wyliczenie Gender
„( Male =0 , Female =1
) i mam inne wyliczenie z usługi, która ma własną wyliczenie rodzaju ( Male =0 , Female =1, Unknown =2
)
Moje pytanie brzmi: jak mogę napisać coś szybko i przyjemnie, aby przekonwertować je z ich wyliczenia na moje?
Odpowiedzi:
Użycie metody rozszerzenia działa całkiem nieźle, gdy używa się dwóch metod konwersji sugerowanych przez Nate'a:
Oczywiście nie ma potrzeby używania oddzielnych klas, jeśli nie chcesz. Preferuję zachowanie metod rozszerzających pogrupowanych według klas / struktur / wyliczeń, do których mają zastosowanie.
źródło
Biorąc pod uwagę
Enum1 value = ...
, jeśli masz na myśli imię:Jeśli masz na myśli wartość liczbową, zwykle możesz rzucić:
(w przypadku rzutowania możesz jednak chcieć użyć
Enum.IsDefined
do sprawdzenia prawidłowych wartości)źródło
Enum.Tryparse
:Enum2 value2 = Enum.TryParse(value.ToString(), out Enum2 outValue) ? outValue : Enum2.Unknown;
Pozwoli ci to obsłużyć wartości wejściowe, które nie istnieją,Enum2
bez konieczności wywoływaniaEnum.IsDefined
lub przechwytywaniaArgumentException
wyrzuconych przezEnum.Parse
. Zauważ, że kolejność parametrów jest mniej więcej odwrócona odEnum.Parse
.Po prostu rzuć jeden na int, a następnie przerzuć go na drugie wyliczenie (biorąc pod uwagę, że chcesz mapować na podstawie wartości):
źródło
long
(lubulong
), a nie,int
które ma członków zdefiniowanych powyżejint.MaxValue
(lub poniżej)int.MinValue
), w którym to przypadku rzutowanie naint
może się przepełnić i otrzymamy niezdefiniowaną wartość wyliczenia, która powinna zostać zdefiniowana.Aby być dokładnym, zwykle tworzę parę funkcji, jedną, która pobiera Enum 1 i zwraca Enum 2, a drugą, która pobiera Enum 2 i zwraca Enum 1. Każda składa się z instrukcji case mapującej dane wejściowe na wyjścia, a przypadek domyślny zgłasza wyjątek z komunikat narzekający na nieoczekiwaną wartość.
W tym konkretnym przypadku możesz skorzystać z faktu, że wartości całkowite płci męskiej i żeńskiej są takie same, ale unikałbym tego, ponieważ jest to hacking i może ulec uszkodzeniu, jeśli którekolwiek wyliczenie zmieni się w przyszłości.
źródło
Jeśli mamy:
i
Możemy to zrobić bezpiecznie
Lub nawet
Jeśli chcesz uwzględnić przypadek, w którym wyliczenie po prawej stronie znaku „=” ma więcej wartości niż wyliczenie po lewej stronie - będziesz musiał napisać własną metodę / słownik, aby to uwzględnić, tak jak sugerowali inni.
źródło
Możesz napisać prostą, ogólną metodę rozszerzenia, taką jak ta
źródło
możesz napisać prostą funkcję, taką jak:
źródło
Oto wersja metody rozszerzenia, jeśli ktoś jest zainteresowany
źródło
źródło
Jakiś czas temu napisałem zestaw metod rozszerzających, które działają dla kilku różnych rodzajów
Enum
. Jeden w szczególności działa dla tego, co próbujesz osiągnąć i obsługujeEnum
s zFlagsAttribute
orazEnum
z różnymi podstawowymi typami.Stamtąd możesz dodać inne, bardziej szczegółowe metody rozszerzeń.
Ten zmieni typy,
Enum
tak jak próbujesz to zrobić.Ostrzegamy jednak, że MOŻESZ konwertować między dowolnymi
Enum
innymiEnum
przy użyciu tej metody, nawet tymi, które nie mają flag. Na przykład:Zmienna
turtle
będzie miała wartośćTurtle.Blue
.Jednak
Enum
użycie tej metody zapewnia bezpieczeństwo przed niezdefiniowanymi wartościami. Na przykład:W tym przypadku
access
zostanie ustawiony naWriteAccess.ReadWrite
, ponieważWriteAccess
Enum
maksymalna wartość wynosi 3.Innym efektem ubocznym mieszania
Enum
s z tymiFlagsAttribute
i bez niego jest to, że proces konwersji nie spowoduje dopasowania 1 do 1 między ich wartościami.W tym przypadku
letters
będzie miał wartośćLetters.H
zamiastLetters.D
, ponieważ wartość bazowaFlavors.Peach
wynosi 8. Ponadto przyniosłaby konwersja zFlavors.Cherry | Flavors.Grape
na , co może wydawać się nieintuicyjne.Letters
Letters.C
źródło
Na podstawie powyższej odpowiedzi Justina wymyśliłem to:
źródło
Wiem, że to stare pytanie i mam wiele odpowiedzi, jednak uważam, że użycie instrukcji przełącznika, tak jak w zaakceptowanej odpowiedzi, jest nieco uciążliwe, więc oto moje 2 centy:
Moją ulubioną metodą jest użycie słownika, w którym kluczem jest wyliczenie źródłowe, a wartością jest wyliczenie docelowe - więc w przypadku przedstawionym na pytaniu mój kod wyglądałby tak:
Oczywiście można to opakować w klasę statyczną i wykorzystać jako metody rozszerzające:
źródło
Możesz użyć ToString (), aby przekonwertować pierwsze wyliczenie na jego nazwę, a następnie Enum.Parse (), aby przekonwertować ciąg z powrotem do drugiego Enum. Spowoduje to zgłoszenie wyjątku, jeśli wartość nie jest obsługiwana przez docelowe wyliczenie (np. Dla wartości „Nieznane”)
źródło