Jak można int
rzucić enum
w C #?
3189
Z ciągu:
YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);
// The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
{
throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.")
}
Od int:
YourEnum foo = (YourEnum)yourInt;
Aktualizacja:
Z numeru możesz także
YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
YourEnum
jest dynamiczny i będzie znany tylko w środowisku wykonawczym, a to, czego chcę, to konwersjaEnum
?var result = Enum.TryParse(yourString, out yourEnum)
obecnie (i sprawdzać wynik, aby ustalić, czy konwersja nie powiodła się).Enum.Parse
rozróżniać małe i wielkie litery, dodająctrue
wartość parametru do wywołania:YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString, true);
Po prostu rzuć to:
Możesz sprawdzić, czy jest w zasięgu za pomocą Enum.IsDefined :
źródło
Enum.IsDefined
, należy pamiętać, że może to być niebezpieczne: msdn.microsoft.com/en-us/library/ms229025(VS.90).aspxIsDefined
sprawdzania wartości wejściowych narażasz się na ryzyko, że ludzie dodadzą nowe wartości wyliczenia później, co przejdzieIsDefined
kontrolę (od czasu nowej wartość istnieje w nowym kodzie), ale może nie działać z oryginalnym kodem, który napisałeś. Dlatego bezpieczniej jest jawnie określić wartości wyliczeniowe, które twój kod jest w stanie obsłużyć.Alternatywnie użyj metody rozszerzenia zamiast jednowarstwowej:
Stosowanie:
LUB
źródło
System.String
wydaje się jak zanieczyszczenie przestrzeni nazwMyślę, że aby uzyskać pełną odpowiedź, ludzie muszą wiedzieć, jak wyliczenia działają wewnętrznie w .NET.
Jak działają rzeczy
Wyliczenie w .NET to struktura, która odwzorowuje zestaw wartości (pól) na typ podstawowy (domyślnie jest
int
). Możesz jednak wybrać typ całki, na który odwzorowuje twój enum:W tym przypadku wyliczenie jest odwzorowane na
short
typ danych, co oznacza, że zostanie zapisane w pamięci jako krótkie i będzie zachowywać się jak krótkie po rzutowaniu i użyciu.Jeśli spojrzysz na to z punktu widzenia IL, wyliczenie (normalne, int) wygląda następująco:
Należy zwrócić uwagę na to, że
value__
są przechowywane oddzielnie od wartości wyliczeniowych. W przypadkuFoo
powyższego wyliczenia typemvalue__
jest int16. Zasadniczo oznacza to, że możesz przechowywać, co chcesz, w wyliczeniu, o ile typy są zgodne .W tym miejscu chciałbym wskazać, że
System.Enum
jest to typ wartości, co w zasadzie oznacza, żeBarFlag
zajmie 4 bajty w pamięci iFoo
zajmie 2 - np. Rozmiar typu bazowego (jest to w rzeczywistości bardziej skomplikowane, ale Hej...).Odpowiedź
Jeśli więc masz liczbę całkowitą, którą chcesz zmapować do wyliczenia, środowisko wykonawcze musi tylko zrobić 2 rzeczy: skopiować 4 bajty i nazwać to czymś innym (nazwa wyliczenia). Kopiowanie jest niejawne, ponieważ dane są przechowywane jako typ wartości - oznacza to po prostu, że jeśli używasz niezarządzanego kodu, możesz po prostu zamieniać wyliczenia i liczby całkowite bez kopiowania danych.
Dla bezpieczeństwa uważam, że najlepszą praktyką jest wiedzieć, że typy bazowe są takie same lub domyślnie konwertowalne oraz aby zapewnić istnienie wartości wyliczeniowych (domyślnie nie są sprawdzane!).
Aby zobaczyć, jak to działa, wypróbuj następujący kod:
Pamiętaj, że rzutowanie
e2
również działa! Z powyższego punktu widzenia kompilatora ma to sens:value__
pole jest po prostu wypełnione albo 5 albo 6, a kiedyConsole.WriteLine
wywołaniaToString()
, nazwae1
zostaje rozwiązana, a nazwae2
nie.Jeśli nie jest to zamierzone, użyj,
Enum.IsDefined(typeof(MyEnum), 6)
aby sprawdzić, czy wartość rzutujesz mapy do zdefiniowanego wyliczenia.Zauważ też, że wyrażam się jasno o podstawowym typie wyliczenia, nawet jeśli kompilator faktycznie to sprawdza. Robię to, aby upewnić się, że nie spotka mnie żadna niespodzianka. Aby zobaczyć te niespodzianki w akcji, możesz użyć następującego kodu (faktycznie widziałem, że tak się często dzieje w kodzie bazy danych):
źródło
int
! =short
, Wyrzuci (rozpakowanie nie powiedzie się). Jeśli to zrobiszobject o = (short)5;
, będzie działać, ponieważ wtedy typy będą pasować. Nie chodzi o zakres, ale o typ.Weź następujący przykład:
źródło
Korzystam z tego fragmentu kodu, aby rzucić int do mojego wyliczenia:
Uważam to za najlepsze rozwiązanie.
źródło
Poniżej znajduje się niezła klasa użyteczności dla Enums
źródło
W przypadku wartości liczbowych jest to bezpieczniejsze, ponieważ zwróci obiekt bez względu na wszystko:
źródło
Jeśli jesteś gotowy na 4.0 .NET Framework, dostępna jest nowa funkcja Enum.TryParse (), która jest bardzo przydatna i dobrze współpracuje z atrybutem [Flagi]. Zobacz Enum.TryParse Method (String, TEnum%)
źródło
Jeśli masz liczbę całkowitą, która działa jak maska bitowa i może reprezentować jedną lub więcej wartości w wyliczeniu [Flagi], możesz użyć tego kodu, aby przeanalizować poszczególne wartości flagi na liście:
Zauważ, że zakłada to, że podstawowym typem
enum
jest 32-bitowa liczba całkowita ze znakiem. Gdyby był to inny typ liczbowy, musiałbyś zmienić kod 32, aby odzwierciedlić bity tego typu (lub programowo wyprowadzić go za pomocąEnum.GetUnderlyingType()
)źródło
Czasami masz obiekt tego
MyEnum
typu. LubićNastępnie:
źródło
Jest to metoda bezpiecznej konwersji z uwzględnieniem wyliczania flag:
źródło
Enum
zamiaststruct
, co oznacza, że nie musimy polegać na kontroli środowiska wykonawczego!Aby przekonwertować ciąg znaków na ENUM lub int na stałą ENUM, musimy użyć funkcji Enum.Parse. Oto film z youtube https://www.youtube.com/watch?v=4nhx4VwdRDk, który faktycznie pokazuje ciąg znaków i to samo dotyczy int.
Kod wygląda tak, jak pokazano poniżej, gdzie „czerwony” to ciąg znaków, a „MyColors” to kolor ENUM, który ma stałe kolorów.
źródło
Nieco uciekam od pierwotnego pytania, ale znalazłem odpowiedź na pytanie Przepełnienie stosu Uzyskaj wartość int z enum przydaje się. Utwórz klasę statyczną o
public const int
właściwościach, która pozwoli ci łatwo zebrać razem kilka powiązanychint
stałych, a następnie nie musisz ich rzutowaćint
podczas ich używania.Oczywiście niektóre funkcje typu wyliczania zostaną utracone, ale do przechowywania szeregu stałych identyfikatora bazy danych wydaje się to dość uporządkowane rozwiązanie.
źródło
To analizuje liczby całkowite lub ciągi do docelowego wyliczenia z częściowym dopasowaniem w dot.NET 4.0 przy użyciu ogólnych, takich jak w klasie użyteczności Tawani powyżej. Używam go do konwersji zmiennych przełączników wiersza polecenia, które mogą być niekompletne. Ponieważ wyliczenie nie może mieć wartości null, należy logicznie podać wartość domyślną. Można to nazwać tak:
Oto kod:
FYI: Pytanie dotyczyło liczb całkowitych, o których nikt nie wspomniał, które również zostaną jawnie przekonwertowane w Enum.TryParse ()
źródło
Z ciągu: (Enum.Parse jest nieaktualny, użyj Enum.TryParse)
źródło
Poniżej znajduje się nieco lepsza metoda rozszerzenia
źródło
W moim przypadku musiałem zwrócić wyliczenie z usługi WCF. Potrzebowałem także przyjaznej nazwy, nie tylko enum.ToString ().
Oto moja klasa WCF.
Oto metoda Extension, która pobiera Opis z Enum.
Realizacja:
źródło
Nie wiem już, skąd biorę część tego rozszerzenia enum, ale pochodzi ono z przepełnienia stosu. Przepraszam za to! Ale wziąłem ten i zmodyfikowałem dla wyliczeń za pomocą Flags. W przypadku wyliczeń z flagami zrobiłem to:
Przykład:
źródło
Powinieneś wbudować relaksację dopasowaną do typu, aby być bardziej niezawodnym.
Przypadek testowy
źródło
Różne sposoby przesyłania do iz
Enum
źródło
Może pomóc ci przekonwertować dowolne dane wejściowe na żądane przez użytkownika wyliczenie . Załóżmy, że masz wyliczenie jak poniżej, które domyślnie int . Dodaj wartość domyślną na początku swojego wyliczenia. Który jest używany w pomocnikach medthod, gdy nie znaleziono dopasowania z wartością wejściową.
NB: Tutaj próbuję parsować wartość na int, ponieważ enum jest domyślnie int Jeśli zdefiniujesz enum jak ten, który jest typem bajtu .
Musisz zmienić parsowanie w metodzie pomocniczej z
do
byte.TryParse(value.ToString(), out tempType)
Sprawdzam moją metodę pod kątem następujących danych wejściowych
przepraszam za mój angielski
źródło
Oto metoda rozszerzenia, która przesyła
Int32
doEnum
.Uwzględnia flagi bitowe, nawet jeśli wartość jest wyższa niż maksymalna możliwa. Na przykład, jeśli masz wyliczenie z możliwościami 1 , 2 i 4 , ale int wynosi 9 , rozumie to jako 1 przy braku 8 . Umożliwia to aktualizację danych przed aktualizacją kodu.
źródło
prosty i przejrzysty sposób na rzutowanie int na wyliczenie w c #:
źródło
Wystarczy użyć jawnej konwersji Cast int na enum lub enum na int
źródło
źródło
Po prostu lubisz poniżej:
Aby upewnić się, że rzucisz tylko prawidłowe wartości i że możesz wrzucić wyjątek:
Pamiętaj, że korzystanie z IsDefined jest kosztowne, a nawet więcej niż tylko rzutowanie, więc decyzja o jego użyciu zależy od implementacji.
źródło
Możesz użyć metody rozszerzenia.
użyj jak poniżej kodu
wyliczenie:
Stosowanie :
źródło