Ich möchte eine Funktion schreiben, die einen bestimmten Wert (als Zeichenfolge übergeben) anhand möglicher Werte von a validieren kann enum
. Im Falle einer Übereinstimmung sollte die Aufzählungsinstanz zurückgegeben werden. Andernfalls sollte ein Standardwert zurückgegeben werden.
Die Funktion verwendet try
/ möglicherweise nicht intern catch
, was die Verwendung ausschließt Enum.Parse
, wodurch eine Ausnahme ausgelöst wird , wenn ein ungültiges Argument angegeben wird.
Ich möchte etwas in der Art einer TryParse
Funktion verwenden, um dies zu implementieren:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
Antworten:
Wie andere gesagt haben, müssen Sie Ihre eigenen implementieren
TryParse
. Simon Mourier bietet eine vollständige Implementierung, die sich um alles kümmert.Wenn Sie Bitfeld-Aufzählungen (dh Flags) verwenden, müssen Sie auch eine Zeichenfolge behandeln, bei
"MyEnum.Val1|MyEnum.Val2"
der es sich um eine Kombination aus zwei Aufzählungswerten handelt. Wenn Sie nurEnum.IsDefined
mit dieser Zeichenfolge aufrufen , wird false zurückgegeben, obwohlEnum.Parse
dies korrekt behandelt wird.Aktualisieren
Wie von Lisa und Christian in den Kommentaren erwähnt,
Enum.TryParse
ist es jetzt für C # in .NET4 und höher verfügbar.MSDN Docs
quelle
Enum.IsDefined erledigt alles. Es ist möglicherweise nicht so effizient wie ein TryParse, funktioniert aber ohne Ausnahmebehandlung.
Bemerkenswert:
TryParse
In .NET 4.0 wurde eine Methode hinzugefügt.quelle
GetNames
. Intern verwenden alle diese Methoden (einschließlichParse
)GetHashEntry
die eigentliche Reflexion - einmal. Auf der positiven Seite, .NET 4.0 hat eine TryParse, und es ist auch generisch :)Hier ist eine benutzerdefinierte Implementierung von
EnumTryParse
. Im Gegensatz zu anderen gängigen Implementierungen unterstützt es auch die mit demFlags
Attribut gekennzeichnete Aufzählung .quelle
Activator.CreateInstance(type)
den Standard-Enum-Wert erstellen und nichtEnum.ToObject(type, 0)
. Nur Geschmackssache?Am Ende müssen Sie dies umsetzen
Enum.GetNames
:Zusätzliche Bemerkungen:
Enum.TryParse
ist in .NET 4 enthalten. Siehe hier http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
die Ausnahme, die ausgelöst wird, wenn sie fehlschlägt , direkt zu verpacken . Dies kann schneller sein, wenn eine Übereinstimmung gefunden wird, wird aber wahrscheinlich langsamer, wenn nicht. Abhängig von den Daten, die Sie verarbeiten, kann dies eine Nettoverbesserung sein oder auch nicht.EDIT: Habe gerade eine bessere Implementierung gesehen, die die notwendigen Informationen zwischenspeichert: http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net- 3-5
quelle
Flags
Attribut.Basierend auf .NET 4.5
Beispielcode unten
Referenz: http://www.dotnetperls.com/enum-parse
quelle
Ich habe eine optimierte Implementierung, die Sie in UnconstrainedMelody verwenden können . Tatsächlich wird nur die Liste der Namen zwischengespeichert, aber dies geschieht auf eine nette, stark typisierte, generisch eingeschränkte Art und Weise :)
quelle
...
quelle
Derzeit gibt es kein sofort einsatzbereites Enum.TryParse. Dies wurde bei Connect angefordert ( noch kein Enum.TryParse ) und erhielt eine Antwort, die auf eine mögliche Aufnahme in das nächste Framework nach .NET 3.5 hinweist. Sie müssen zunächst die vorgeschlagenen Problemumgehungen implementieren.
quelle
Die einzige Möglichkeit, die Ausnahmebehandlung zu vermeiden, ist die Verwendung der GetNames () -Methode. Wir alle wissen, dass Ausnahmen nicht für die allgemeine Anwendungslogik missbraucht werden sollten :)
quelle
Ist das Zwischenspeichern einer dynamisch generierten Funktion / eines Wörterbuchs zulässig?
Da Sie den Typ der Aufzählung nicht im Voraus zu kennen scheinen, könnte die erste Ausführung etwas erzeugen, das nachfolgende Ausführungen ausnutzen könnten.
Sie können sogar das Ergebnis von Enum.GetNames () zwischenspeichern
Versuchen Sie, für CPU oder Speicher zu optimieren? Müssen Sie wirklich ?
quelle
Wie andere bereits sagten, müssen Sie IsDefined oder GetNames verwenden, wenn Sie Try & Catch nicht verwenden ... Hier sind einige Beispiele ... sie sind im Grunde alle gleich, das erste, das nullfähige Aufzählungen behandelt. Ich bevorzuge die zweite, da es sich um eine Erweiterung für Strings handelt, nicht für Enums ... aber Sie können sie mischen, wie Sie möchten!
quelle
Es gibt kein TryParse, da der Typ der Aufzählung erst zur Laufzeit bekannt ist. Ein TryParse, der der gleichen Methode wie die Date.TryParse-Methode folgt, würde einen impliziten Konvertierungsfehler für den ByRef-Parameter auslösen.
Ich schlage vor, so etwas zu tun:
quelle
Try
Methoden, deren Ergebnisse Werttypen seinnull
können oder bei denen es sich möglicherweise um legitime Ergebnisse handelt (z. B.Dictionary.TryGetValue, which has both such traits), the normal pattern is for a
Try`-Methode zum Zurückgebenbool
und Übergeben des Ergebnisses alsout
Parameter). Für Methoden, die Klassentypen zurückgeben, bei denennull
es sich nicht um ein gültiges Ergebnis handelt, gibt es keine Schwierigkeiten bei der Verwendung einernull
Rückgabe um Fehler anzuzeigen.Schauen Sie sich die Enum-Klasse (struct?) Selbst an. Es gibt eine Parse-Methode, aber ich bin mir bei einer Tryparse nicht sicher.
quelle
Diese Methode konvertiert einen Aufzählungstyp:
Es überprüft den zugrunde liegenden Typ und erhält den Namen zum Parsen. Wenn alles fehlschlägt, wird der Standardwert zurückgegeben.
quelle