In .NET Core und .NET> 4 gibt es eine generische Analysemethode :
Enum.TryParse("Active", out StatusEnum myStatus);
Dies schließt auch die neuen Inline- out
Variablen von C # 7 ein , also die Try-Parse, die Konvertierung in den expliziten Aufzählungstyp und die Initialisierung + Auffüllung der myStatus
Variablen.
Wenn Sie Zugriff auf C # 7 und das neueste .NET haben, ist dies der beste Weg.
Ursprüngliche Antwort
In .NET ist es ziemlich hässlich (bis 4 oder höher):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Ich neige dazu, dies zu vereinfachen mit:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Dann kann ich tun:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Eine in den Kommentaren vorgeschlagene Option ist das Hinzufügen einer Erweiterung, die einfach genug ist:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Schließlich möchten Sie möglicherweise eine Standardaufzählung verwenden, wenn die Zeichenfolge nicht analysiert werden kann:
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;
}
Was dies zum Aufruf macht:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Ich würde jedoch vorsichtig sein, wenn ich eine Erweiterungsmethode wie diese hinzufüge, string
da (ohne Namespace-Kontrolle) in allen Fällen string
angezeigt wird, ob sie eine Aufzählung enthalten oder nicht (dies 1234.ToString().ToEnum(StatusEnum.None)
wäre gültig, aber unsinnig). Es ist oft am besten, die Kernklassen von Microsoft nicht mit zusätzlichen Methoden zu überladen, die nur in ganz bestimmten Kontexten gelten, es sei denn, Ihr gesamtes Entwicklungsteam hat ein sehr gutes Verständnis für die Funktionsweise dieser Erweiterungen.
Verwendung
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Mit dem Inlining des Parametertyps von C # 7.0 kann dies noch weiter vereinfacht werden :
quelle
Parse
Wirft erklärende Ausnahmen für das, was bei der Konvertierung schief gelaufen ist (Wert warnull
, leer oder keine entsprechende Enum-Konstante), was viel besser ist alsTryParse
der boolesche Rückgabewert (der den konkreten Fehler unterdrückt)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Beachten Sie, dass die Leistung von
Enum.Parse()
schrecklich ist, da sie über Reflexion implementiert wird. (Dasselbe gilt für dasEnum.ToString
, was in die andere Richtung geht.)Wenn Sie Zeichenfolgen in leistungsabhängigem Code in Enums konvertieren müssen, erstellen Sie am besten eine
Dictionary<String,YourEnum>
beim Start und verwenden Sie diese für Ihre Konvertierungen.quelle
Sie suchen nach Enum.Parse .
quelle
Sie können jetzt Erweiterungsmethoden verwenden :
Und Sie können sie mit dem folgenden Code aufrufen (hier
FilterType
ist ein Aufzählungstyp):quelle
Wenn Sie also eine Aufzählung mit dem Namen Stimmung hätten, würde dies folgendermaßen aussehen:
quelle
IN ACHT NEHMEN:
Enum.(Try)Parse()
akzeptiert mehrere durch Kommas getrennte Argumente und kombiniert sie mit binären 'oder'|
. Sie können dies nicht deaktivieren und meiner Meinung nach wollen Sie es fast nie.Auch wenn
Three
nicht definiert wurde,x
würde immer noch int Wert erhalten3
. Das ist noch schlimmer: Enum.Parse () kann Ihnen einen Wert geben, der nicht einmal für die Aufzählung definiert ist!Ich möchte nicht die Konsequenzen von Benutzern erfahren, die bereitwillig oder unfreiwillig dieses Verhalten auslösen.
Darüber hinaus ist die Leistung, wie von anderen erwähnt, für große Aufzählungen weniger als ideal, nämlich linear in der Anzahl der möglichen Werte.
Ich schlage folgendes vor:
quelle
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Dies bedeutet, dass Sie Ihre Enum-Werte als Zweierpotenzen einrichten können und auf sehr einfache Weise mehrere boolesche Flags analysieren können, z. "UseSSL, NoRetries, Sync". Genau dafür wurde es wahrscheinlich entwickelt.Enum.Parse ist dein Freund:
quelle
Sie können die akzeptierte Antwort um einen Standardwert erweitern, um Ausnahmen zu vermeiden:
Dann nennst du es wie:
Wenn der Standardwert keine Aufzählung ist, schlägt Enum.TryParse fehl und löst eine Ausnahme aus, die abgefangen wird.
Nach Jahren der Verwendung dieser Funktion in unserem Code an vielen Stellen ist es vielleicht gut, die Information hinzuzufügen, dass dieser Vorgang die Leistung kostet!
quelle
defaultValue
Rückgabetyp und der Methodenrückgabetyp sind beide vom TypT
. Wenn die Typen unterschiedlich sind, wird ein Fehler bei der Kompilierung angezeigt: "Konvertierung von 'ConsoleApp1.Size' in 'ConsoleApp1.Color' nicht möglich" oder was auch immer Ihre Typen sind.Wir konnten keine vollkommen gültigen Eingaben annehmen und haben uns für diese Variante der Antwort von @ Keith entschieden:
quelle
quelle
Analysiert den String ohne try / catch und ohne TryParse () -Methode aus .NET 4.5 in TEnum
quelle
Super einfacher Code mit TryParse:
quelle
Ich mag die Lösung der Erweiterungsmethode.
Hier unten meine Implementierung mit Tests.
quelle
==================== Ein vollständiges Programm ====================
quelle
Ich habe class verwendet (stark typisierte Version von Enum mit Analyse und Leistungsverbesserungen). Ich habe es auf GitHub gefunden und es sollte auch für .NET 3.5 funktionieren. Es hat etwas Speicheraufwand, da es ein Wörterbuch puffert.
Der Blogpost lautet Enums - Bessere Syntax, verbesserte Leistung und TryParse in NET 3.5 .
Und Code: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
quelle
Für die Leistung könnte dies helfen:
quelle
Ich fand, dass hier der Fall mit Enum-Werten, die EnumMember-Wert haben, nicht berücksichtigt wurde. Auf geht's:
Und ein Beispiel für diese Aufzählung:
quelle
Sie müssen Enum.Parse verwenden, um den Objektwert von Enum abzurufen. Danach müssen Sie den Objektwert in einen bestimmten Aufzählungswert ändern. Das Umwandeln in einen Aufzählungswert kann mithilfe von Convert.ChangeType erfolgen. Bitte schauen Sie sich das folgende Code-Snippet an
quelle
Probieren Sie dieses Beispiel aus:
In diesem Beispiel können Sie jede Zeichenfolge senden und Ihre festlegen
Enum
. Wenn SieEnum
Daten hatten, die Sie wollten, geben Sie diese als IhrenEnum
Typ zurück.quelle
newModel
jede Zeile. Wenn sie Bindestriche enthält, wird sie nicht ersetzt. Außerdem müssen Sie nicht überprüfen, ob die Zeichenfolge etwas enthält. Sie können sieReplace
trotzdem aufrufen :var newModel = model.Replace("-", "").Replace(" ", "");
Ich bin mir nicht sicher, wann dies hinzugefügt wurde, aber in der Enum-Klasse gibt es jetzt eine
Parse<TEnum>(stringValue)
Wird so mit dem fraglichen Beispiel verwendet:
var MyStatus = Enum.Parse<StatusEnum >("Active")
oder Gehäuse ignorieren durch:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Hier sind die dekompilierten Methoden, die hier verwendet werden:
quelle
quelle
quelle
Wenn sich der Name der Eigenschaft von dem unterscheidet, den Sie nennen möchten (dh Sprachunterschiede), können Sie Folgendes tun:
MyType.cs
EnumExtensions.cs
Program.cs
quelle