W .NET Core i .NET> 4 istnieje ogólna metoda analizy :
Enum.TryParse("Active", out StatusEnum myStatus);
Obejmuje to również nowe out
zmienne wbudowane w C # 7 , więc wykonuje to parsowanie, konwersję do jawnego typu wyliczenia i inicjuje + zapełnia myStatus
zmienną.
Jeśli masz dostęp do C # 7 i najnowszej platformy .NET, jest to najlepszy sposób.
Oryginalna odpowiedź
W .NET jest raczej brzydki (do 4 lub więcej):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Zwykle upraszczam to poprzez:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Następnie mogę zrobić:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Jedną z opcji sugerowanych w komentarzach jest dodanie rozszerzenia, które jest dość proste:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Na koniec możesz chcieć mieć domyślny wyliczenie do użycia, jeśli ciąg nie może zostać przeanalizowany:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
Co sprawia, że jest to połączenie:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Byłbym jednak ostrożny, dodając taką metodę rozszerzenia, string
ponieważ (bez kontroli przestrzeni nazw) pojawi się ona we wszystkich przypadkach, string
czy zawierają wyliczenie, czy nie ( 1234.ToString().ToEnum(StatusEnum.None)
byłoby to prawidłowe, ale bezsensowne). Często najlepiej jest unikać zaśmiecania podstawowych klas Microsoft za pomocą dodatkowych metod, które mają zastosowanie tylko w bardzo specyficznych kontekstach, chyba że cały zespół programistów bardzo dobrze rozumie, co robią te rozszerzenia.
Użyj
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Można to jeszcze bardziej uprościć, wprowadzając typ parametru C # 7.0 :
źródło
Parse
generuje wyjątki objaśniające za to, co poszło nie tak z konwersją (wartość byłanull
, pusta lub nie odpowiadający stałej enum), który jest lepiej niżTryParse
„s logicznej wartości zwracanej (który tłumi błąd beton)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Zauważ, że wydajność
Enum.Parse()
jest okropna, ponieważ jest realizowana poprzez odbicie. (To samo dotyczy sytuacjiEnum.ToString
, która przebiega w drugą stronę).Jeśli chcesz przekonwertować ciągi znaków na Enums w kodzie wrażliwym na wydajność, najlepiej założyć
Dictionary<String,YourEnum>
przy starcie i użyć go do konwersji.źródło
Szukasz Enum.Parse .
źródło
Możesz teraz użyć metod rozszerzenia :
I możesz do nich zadzwonić za pomocą poniższego kodu (tutaj
FilterType
jest typem enum):źródło
Więc jeśli miałeś wyliczenie o nazwie nastrój, wyglądałoby to tak:
źródło
STRZEC SIĘ:
Enum.(Try)Parse()
akceptuje wiele argumentów oddzielonych przecinkami i łączy je z binarnymi „lub”|
. Nie możesz tego wyłączyć i moim zdaniem prawie nigdy tego nie chcesz.Nawet jeśli
Three
nie został zdefiniowany,x
nadal otrzyma wartość int3
. To jeszcze gorzej: Enum.Parse () może dać ci wartość, która nie jest nawet zdefiniowana dla wyliczenia!Nie chciałbym doświadczać konsekwencji użytkowników, dobrowolnie lub niechętnie, wywołujących takie zachowanie.
Ponadto, jak wspomniali inni, wydajność jest mniejsza niż idealna dla dużych wyliczeń, a mianowicie liniowa pod względem liczby możliwych wartości.
Proponuję następujące:
źródło
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Oznacza, że możesz ustawić swoje wartości wyliczeniowe jako potęgi 2 i masz bardzo łatwy sposób na parsowanie wielu flag boolowskich, np. „UseSSL, NoRetries, Sync”. W rzeczywistości prawdopodobnie do tego został przeznaczony.Enum.Parse jest twoim przyjacielem:
źródło
Możesz rozszerzyć akceptowaną odpowiedź o wartość domyślną, aby uniknąć wyjątków:
Następnie nazywacie to tak:
Jeśli wartością domyślną nie jest wyliczanie, Enum.TryParse nie powiedzie się i zgłosi wyjątek, który jest przechwytywany.
Po latach używania tej funkcji w naszym kodzie w wielu miejscach może warto dodać informację, że ta operacja kosztuje wydajność!
źródło
defaultValue
oba typy zwracają metodęT
. Jeśli typy są różne, pojawi się błąd czasu kompilacji: „nie można przekonwertować z„ ConsoleApp1.Size ”na„ ConsoleApp1.Color ”” ani żadnego innego typu.Nie mogliśmy założyć całkowicie poprawnych danych wejściowych i wybraliśmy tę odmianę odpowiedzi @ Keitha:
źródło
źródło
Analizuje ciąg znaków do TEnum bez metody try / catch i bez metody TryParse () z .NET 4.5
źródło
Super prosty kod za pomocą TryParse:
źródło
Podoba mi się metoda metody rozszerzenia.
Tutaj poniżej moja implementacja z testami.
źródło
==================== Kompletny program ====================
źródło
Użyłem klasy (mocno napisana wersja Enum z poprawkami do analizy i wydajności). Znalazłem go na GitHub i powinien on również działać dla .NET 3.5. Ma pewien narzut pamięci, ponieważ buforuje słownik.
Na blogu znajduje się Enums - lepsza składnia, poprawiona wydajność i TryParse w NET 3.5 .
I kod: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
źródło
Dla wydajności może to pomóc:
źródło
Odkryłem, że tutaj nie uwzględniono przypadku z wartościami wyliczenia, które mają wartość EnumMember. Więc zaczynamy:
I przykład tego wyliczenia:
źródło
Musisz użyć Enum.Parse, aby uzyskać wartość obiektu z Enum, a następnie musisz zmienić wartość obiektu na określoną wartość wyliczenia. Rzutowanie na wartość wyliczoną można wykonać za pomocą Convert.ChangeType. Zobacz poniższy fragment kodu
źródło
Wypróbuj tę próbkę:
W tym przykładzie możesz wysłać każdy ciąg i ustawić swój
Enum
. JeśliEnum
posiadałeś dane, które chciałeś, zwróć je jako swójEnum
typ.źródło
newModel
każdą linię, więc jeśli zawiera myślniki, nie zostanie zastąpiona. Ponadto nie musisz sprawdzać, czy ciąg zawiera coś, możesz po prostu zadzwonićReplace
:var newModel = model.Replace("-", "").Replace(" ", "");
Nie jestem pewien, kiedy to zostało dodane, ale w klasie Enum jest teraz
Parse<TEnum>(stringValue)
Używany w ten sposób w przypadku omawianego przykładu:
var MyStatus = Enum.Parse<StatusEnum >("Active")
lub ignorując obudowę przez:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Oto zdekompilowane metody, których używa:
źródło
źródło
źródło
Jeśli nazwa właściwości jest inna niż to, co chcesz nazwać (tj. Różnice językowe), możesz to zrobić w następujący sposób:
MyType.cs
EnumExtensions.cs
Program.cs
źródło