2017-12-13 1 views
6

Ich war überrascht, aber Enums können mit Konstruktor in C# erstellt werden. Zum Beispiel habe ich die Enum:Wie Enum Konstruktoren zu verhindern

public enum Color 
{ 
    White = 1, 
    Red = 2 
} 

Dann könnte es wie folgt erstellt werden:

var color = new Color(); 

Und der Wert 0 sein, die eigentlich nicht gültig Enum-Wert ist.

Also, können wir enum Konstruktoren irgendwie verbieten? Irgendwelche anderen Ideen, wie man das vermeidet?

Danke.

+3

'var color = (Farbe) 125;' ist auch vollkommen legal. Sie müssen manuell überprüfen, ob der Wert gültig ist, wenn Sie die Aufzählungsvariable ... – Haukinger

+1

lesen. Siehe https://msdn.microsoft.com/en-us/library/ms182149.aspx Warum müssen Sie einem non-Wert Werte zuweisen? Flagge enum? – PaulF

+0

0 ist der Standardwert für jeden Werttyp, unabhängig davon, ob er gültig ist oder nicht und kann nicht geändert werden. Wofür benutzt du die enum? Vielleicht könnten wir, wenn wir mehr Kontext hätten, eine Alternative vorschlagen. – Equalsk

Antwort

9

Also, können wir enum Konstruktoren irgendwie verbieten?

Nr Das Problem ist nicht streng an den Konstruktor selbst bezogen werden: (Color)0 gilt auch, da der zugrunde liegende Typ 0 den Wert haben kann.

Irgendwelche anderen Ideen, wie man das vermeidet?

Nein, das ist im Grunde ein breiteres Problem. Sie können dies nur verhindern, indem Sie Ihre Eingabewerte auf Gültigkeit überprüfen.

Sie sollten immer einen 0 Enum-Wert nach Code Analysis haben.

+1

Sie müssen nicht einmal "0" eingeben, um sie einer Aufzählung zuzuordnen. –

+0

@MatthewWatson Einverstanden, aber sonst wäre das Codebeispiel schwer zu verstehen. –

1

Nein, es gibt keine Möglichkeit, es im Allgemeinen zu vermeiden. Sie können einen statischen Analysator warnen lassen, aber es löst nicht das zugrunde liegende Problem, dass eine Aufzählung nur eine Zahl ist und als solche den Wert 123 haben kann. Üblicherweise wird es den Wert Null haben (wenn Sie es zum Beispiel neu eingeben, oder weise es nicht zu).

das Problem deutlicher zu sehen, betrachten Sie dieses:

var colors = new Color[100]; 

Was colors[0] jetzt ist? Es ist null, wie jede nicht initialisierte Nummer. Eine Enumeration ermöglicht es Ihnen also, Werte zu benennen - das garantiert nicht, dass Variablen des Typs einen dieser benannten Werte verwenden.

Eine gute Best Practice besteht darin, in Ihrer Enumeration immer einen Namen-Wert für Null zu haben (normalerweise würde es in diesem Fall "None", "Uninitialized", "NotSet" oder Ähnliches heißen). Sobald Sie das haben, werden die nicht initialisierten Werte sinnvoll sein.

1

public enum Color ist eigentlich die verkürzte Form der vollständigen Deklaration einer Enum, die public enum Color : int wäre.

Eine enum immer hat einen zugrunde liegenden Basistyp und ist technisch einfach eine Variable dieses Typs. Standardmäßig ist dieser Typ eine 32-Bit-Ganzzahl, dh jede 32-Bit-Ganzzahl kann einer solchen Enumeration zugewiesen werden.

Die eigentlichen enum-Definitionen sind lediglich benannte Elemente dieses Typs zur einfachen Verwendung in der Programmierung, sodass Sie die zugrunde liegenden Werte ändern oder sogar vollständig ignorieren können, ohne den Code ändern zu müssen.

aber intern alle Aufzählungen Ihrer Art Color (schrecklicher Name, übrigens) sind nur Int32-Werte und as Anders Forsgren pointed out, wie jeder andere Int32-Wert, werden sie auf 0 in Arrays und jede Art von globalen Variablen standardmäßig. Dies ist auch der Grund, warum die offiziellen Richtlinien empfehlen, immer eine 0-Definition in Ihr Enum zu setzen.