Warum erstellt Enum.Parse nicht definierte Einträge?

8
%Vor%

Wenn Sie den obigen Code ausführen, zeigt das Ergebnis:

  

Sie sollten mindestens eine 12345 pro Tag essen.

Ich habe wirklich erwartet, dass eine ArgumentException ausgelöst wird, wenn ein unbekannter Name (String) übergeben wird. Wenn Sie sich die Enum.Parse-Definition genauer ansehen, wird Folgendes angezeigt:

  

Zusammenfassung:
  Konvertiert die Zeichenfolgendarstellung des Namens oder des numerischen Werts einer oder mehrerer Aufzählungskonstanten in ein äquivalentes Aufzählungsobjekt.

     

Ausnahmen:
ArgumentException : enumType ist keine Enumeration. -oder- Wert ist entweder eine leere Zeichenfolge oder enthält nur Leerzeichen. -oder- Wert ist ein Name, aber nicht eine der benannten Konstanten, die für die Aufzählung definiert sind.

i.e. Wenn eine Zeichenfolgendarstellung einer Ganzzahl übergeben wird, wird ein neuer enum-Wert erstellt und jetzt wird die Ausnahme vom Entwurf ausgelöst. Macht das Sinn?

Zumindest kann ich nun Enum.IsDefined(enumType, value) vor Enum.Parse()

aufrufen     
Markus 26.08.2010, 12:50
quelle

4 Antworten

4

Die "benannte Konstante" ist die textuelle Darstellung eines Enum-Werts, nicht die Nummer, die Sie ihm zugewiesen haben.

Wenn Sie ändern:

%Vor%

An:

%Vor%

Sie werden den erwarteten Fehler sehen, weil "value ein Name ist, aber keine der benannten Konstanten, die für die Enumeration definiert sind". In diesem Fall ist der Wert, den Sie in übergeben, ein Name, "Kuchen", aber keiner in der Aufzählung.

Denken Sie an Enum.Parse(enumType, value); , wenn Sie Folgendes tun:

  1. Wenn value eine Nullreferenz ist, werfen Sie eine ArgumentNullException
  2. Ist der Wert in value eine der benannten Konstanten in der Enumeration in enumType . Wenn ja, gebe diesen Wert von der Aufzählung zurück und stoppe.
  3. Ist der Wert in value direkt in den zugrunde liegenden Typ konvertierbar (in diesem Fall Int32), falls ja, gebe diesen Wert zurück und stoppe (, auch wenn für diesen Wert keine benannte Konstante angegeben ist ).
  4. Ist der Wert in value direkt in den zugrunde liegenden Typ konvertierbar, aber außerhalb des Bereichs des zugrunde liegenden Typs? z.B. Der Wert ist eine Zeichenfolge, die eine Nummer größer als MAXINT enthält. Wenn ja, wirf ein OverflowException .
  5. Kann der Wert nicht auf den zugrunde liegenden Typ angewendet werden? Wenn ja, werfen Sie eine ArgumentException.
Rob 26.08.2010, 12:56
quelle
3

Eine Aufzählung kann ein beliebiger Wert des Basis-Integer-Typs sein. Es ist nicht nur auf benannte Konstanten beschränkt.

Zum Beispiel ist das Folgende vollkommen richtig:

%Vor%

Auch wenn 5 keiner benannten Konstante entspricht, ist es immer noch ein gültiger Wert für Foo , da der zugrunde liegende Typ für Foo Int32 ist.

Wenn man x.ToString() aufrufen würde, wäre der zurückgegebene Wert einfach "5", da keine benannte Konstante mit dem Wert von x übereinstimmt.

Enum.Parse() ist die umgekehrte Funktion von Enum.ToString() . Sie sollten erwarten, dass was auch immer Enum.ToString() zurückgeben kann, dass Enum.Parse() akzeptieren kann. Dazu gehören beispielsweise durch Kommas getrennte Werte für Flag-Enums:

%Vor%

Ausgabe:

%Vor%

BEARBEITEN:

Was du wirklich zu haben scheinst, ist etwa so:

%Vor%

oder eine Groß- / Kleinschreibung nicht beachten:

%Vor%     
P Daddy 26.08.2010 13:34
quelle
0

Sie müssen Enum.IsDefined verwenden:

Ссылка

%Vor%     
Dave Swersky 26.08.2010 12:53
quelle
0

Ich persönlich finde es schade, dass Enum.Parse die String-Darstellung einer Zahl akzeptiert. Wenn Sie nach einer Alternative suchen, sollten Sie sich vielleicht mein Projekt Unconstrained Melody ansehen, das verschiedene Analyseoptionen bietet und stark ist getippt auch.

Sie können in Verbindung mit dem Parsing Enum.IsDefined verwenden. Wollen Sie auf jeden Fall Zeichenfolgenversionen von Zahlen akzeptieren? Oder erwarten Sie wirklich nur Namen?

    
Jon Skeet 26.08.2010 12:53
quelle

Tags und Links