Ich habe ein paar SO-Beiträge gelesen und es scheint, dass die grundlegendste Operation fehlt.
public enum LoggingLevel
{
Off = 0,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Trace = 5
};
if (s == "LogLevel")
{
_log.LogLevel = (LoggingLevel)Convert.ToInt32("78");
_log.LogLevel = (LoggingLevel)Enum.Parse(typeof(LoggingLevel), "78");
_log.WriteDebug(_log.LogLevel.ToString());
}
Dies verursacht keine Ausnahmen, es ist gerne zu speichern 78
. Gibt es eine Möglichkeit, einen Wert zu validieren, der in eine Aufzählung eingeht?
Antworten:
Schauen Sie sich Enum.IsDefined an
Verwendung:
Dies ist das Beispiel von dieser Seite:
Das Beispiel zeigt die folgende Ausgabe:
quelle
LoggingLevel
die als Speicher verwendet wird, und präsentiere diese dann alsLoggingLevel
Aufzählungswert.IsDefined
nicht für bitwised Enum-Mitglieder zu funktionieren.Die obigen Lösungen behandeln keine
[Flags]
Situationen.Meine unten stehende Lösung kann einige Leistungsprobleme aufweisen (ich bin sicher, dass man sie auf verschiedene Arten optimieren kann), aber im Wesentlichen wird immer bewiesen, ob ein Aufzählungswert gültig ist oder nicht .
Es beruht auf drei Annahmen:
int
, absolut nichts anderes-
Aufruf
ToString()
auf einer ENUM gibt entweder denint
Wert , wenn kein ENUM (Flag oder nicht) abgestimmt ist. Wenn ein zulässiger Aufzählungswert übereinstimmt, wird der Name der Übereinstimmung (en) gedruckt.So:
Unter Berücksichtigung dieser beiden Regeln können wir davon ausgehen, dass bei korrekter Ausführung von .NET Framework alle Aufrufe einer gültigen Enum-
ToString()
Methode zu etwas führen, dessen erstes Zeichen ein alphabetisches Zeichen ist:Man könnte es als "Hack" bezeichnen, aber die Vorteile sind, dass
Enum
Sie sich nicht auf Ihren eigenen potenziell fehlerhaften Code oder Ihre eigenen Überprüfungen verlassen, wenn Sie sich auf Microsofts eigene Implementierung von und C # -Standards verlassen. In Situationen, in denen die Leistung nicht außergewöhnlich kritisch ist, werden dadurch viele böseswitch
Aussagen oder andere Überprüfungen eingespart!Bearbeiten
Vielen Dank an @ChaseMedallion für den Hinweis, dass meine ursprüngliche Implementierung keine negativen Werte unterstützt. Dies wurde behoben und Tests bereitgestellt.
Und die Tests, um es zu sichern:
quelle
[Flags]
sie vernünftige ganzzahlige Werte haben.Die kanonische Antwort wäre
Enum.IsDefined
, aber das ist a: ein bisschen langsam, wenn es in einer engen Schleife verwendet wird, und b: nicht nützlich für[Flags]
Aufzählungen.Persönlich würde ich aufhören, mir darüber Sorgen zu machen, und
switch
mich nur angemessen daran erinnern:default:
(oder lassen Sie eine leeredefault:
Erklärung, warum).default:
Wie so:
quelle
Verwenden:
quelle
Verwenden Sie Enum.IsDefined .
quelle
Um damit umzugehen
[Flags]
, können Sie auch diese Lösung aus dem C # -Kochbuch verwenden :ALL
Fügen Sie Ihrer Aufzählung zunächst einen neuen Wert hinzu:Überprüfen Sie dann, ob der Wert in
ALL
:quelle
Eine Möglichkeit wäre, sich auf Casting und Enum-to-String-Konvertierung zu verlassen. Beim Umwandeln von int in einen Aufzählungstyp wird das int entweder in einen entsprechenden Aufzählungswert konvertiert oder die resultierende Aufzählung enthält nur int als Wert, wenn für das int kein Aufzählungswert definiert ist.
Nicht für Randfälle getestet.
quelle
Wie die anderen sagten, wird
Enum.IsDefined
zurückgegeben,false
auch wenn Sie eine gültige Kombination von Bit-Flags für eine Aufzählung haben, die mit dem verziert istFlagsAttribute
.Leider ist die einzige Möglichkeit, eine Methode zu erstellen, die true für gültige Bitflags zurückgibt, etwas langwierig:
Möglicherweise möchten Sie die Ergebnisse von
GetCustomAttribute
in einem Wörterbuch zwischenspeichern:Beachten Sie, dass der obige Code die neue
Enum
Einschränkung verwendet,T
die nur seit C # 7.3 verfügbar ist. Sie müssen einobject value
in älteren Versionen übergeben und es aufrufenGetType()
.quelle