Sollten enums nicht initialisierte Werte haben.

8

Wir hatten eine Debatte, ob enums nicht initialisierte Werte haben sollten. Beispielsweise. Wir haben

%Vor%

oder

%Vor%

Ich denke, dass es keine geben sollte, aber dann muss man bei der Initialisierung auf einen gültigen Wert zurückgreifen. Aber andere dachten, dass es einen Hinweis auf den unitize-Status geben sollte, indem sie ein anderes enum haben, das None oder NotSet ist.

Gedanken?

    
leora 06.12.2008, 02:07
quelle

6 Antworten

13

Wenn wir von nullbaren Typen sprechen - ich denke, sie können verwendet werden, um das Problem zu lösen, die Initialisierung eines Enums zu erzwingen / nicht zu erzwingen. Sagen wir, wir haben

%Vor%

Und sagen wir, Sie haben eine Funktion:

%Vor%

Diese Funktion besagt, dass eine gültige Color erfordert. Wir könnten jedoch auch diese Funktion haben:

%Vor%

Das besagt, dass die Funktion damit umgehen kann, keine Farbe zu übergeben ( null würde übergeben, um "egal" anzuzeigen).

Nun, es ist eine Alternative zu None members.

    
Frank Krueger 06.12.2008, 02:33
quelle
7

Ich setze immer einen meiner enum-Literale auf Null. Dieses Literal muss nicht immer "None" oder "NotSet" heißen. Es hängt davon ab, ob es ein Literal gibt, das sich sehr gut als Standard verhält.

Ich setze eins auf Null, weil Enums (außer Nullable enums) immer von der CLR im Speicher auf Null initialisiert werden. Und wenn Sie eines der Literale nicht definieren, enthält dieser Speicher ungültige Werte. Auch wenn Sie Enums als Flags verwenden. Der Standardwert kann nicht für bitweise Vergleiche verwendet werden. Das Ergebnis ist immer Null.

Wenn Sie FxCop aktivieren, prüft es, ob Sie ein Literal als Standard definiert haben. Scheint eine "gute Praxis" zu sein, wenn sie eine Regel dafür haben.

    
TomTom 06.12.2008 08:32
quelle
4

In einigen der vorherigen Antworten wurde ein NULL-fähiges Enum als Lösung vorgeschlagen. Eine Nullable-Enumeration hat jedoch den Nachteil, dass Clients bei jedem Aufruf der Enumeration nach einem Nullwert suchen müssen. Wenn Sie dagegen einen Standardwert von "None" haben, können Sie einen Schalter für die sinnvollen Werte verwenden und einfach "None" ignorieren, ohne befürchten zu müssen, dass die enum-Variable null sein könnte.
< br> Wie auch immer, ich denke, einen Standardwert von "None" zu haben oder die Enum-NULL-Option zu machen, macht nur Sinn, wenn die Enumeration als Argument in einem Standardkonstruktor für eine Klasse verwendet wird. Und Sie müssen sich selbst fragen - sollten die Objekte dieser Klasse keinen sinnvollen Standardwert haben? Verwenden Sie Ihr Beispiel mit der TimeOfDayType-Enumeration - wenn Sie ein Objekt mit TimeOfDayType.None initialisieren, können Sie es sowieso nicht verwenden, bevor Sie den Wert in Morning, Afternoon oder Evening ändern. Könntest du nicht sagen, dass der Standard Morning statt None ist? Oder - was noch besser ist - könnten Sie Ihre Objekte nicht erstellen, nachdem Sie bereits wissen, welchen Aufzählungswert sie benötigen? Ich denke, wenn das Problem in den frühen Entwurfsphasen richtig angegangen wird, sollten Sie keinen speziellen Standardwert für Ihre Enums benötigen.

Natürlich ist das alles eine Verallgemeinerung. Vielleicht kann es nicht auf Ihr spezielles Szenario angewendet werden. Wenn Sie einige Details dazu angeben, könnten wir das Problem genauer diskutieren.

    
Boyan 06.12.2008 04:00
quelle
4

In der Abwesenheit eines "Standard" -Mitglieds halte ich es für sinnvoll, einen Wert zu haben, der das Literal int 0 darstellt.

Egal wie, eine gegebene Enumeration wird mit dem Literalwert 0 erzeugt. Der einfachste Fall ist hier ein Member einer Struktur. Eine C # -Struktur hat immer einen leeren Standardkonstruktor, der alle Felder auf ihren Standardwert initialisiert. Im Falle einer Aufzählung ist das der Literalwert 0. Die Frage ist, wie man damit umgeht.

Für mich ist das eine Frage des Stils: Wenn die Enumeration nicht explizit auf einen Wert initialisiert wird, sollte ihr ein beliebiger gültiger Wert oder ein bestimmter Wert gegeben werden, der auf eine fehlende explizite Initialisierung hinweist?

%Vor%

Falls v1 das Farbfeld überprüft wird, wird es explizit als nicht initialisiertes Feld gekennzeichnet. In v2 wird das Feld einfach "Rot" sein. Es gibt keine Möglichkeit für einen Programmierer, zwischen "Explizit" und "Rot" oder einem impliziten Standardwert für "Rot" zu erkennen.

Ein anderer Fall, in dem dies ein Problem verursacht, ist eine switch-Anweisung gegen einen enum-Wert. Lässt leicht die Definition von Color2 ändern.

%Vor%

Der Schalter behandelt jeden expliziten Wert in der Aufzählung. Dieser Code wird jedoch für den Standardkonstruktor von Beispiel & lt; Color2 & gt; und es gibt keine Möglichkeit, diesen Konstruktor zu unterdrücken.

Dies führt zu einer etwas wichtigeren Regel: Sie müssen einen expliziten Aufzählungswert für den Literalwert 0 haben.

    
JaredPar 06.12.2008 04:01
quelle
3

Wenn ich nur zu Franks Antwort hinzufüge, wäre eines der wenigen Male, dass ich mich für ein "None" -Element in einer Enum-NULL-Option entscheiden würde, wenn die Enumeration als Flags verwendet wird. Der Eintrag 'None' würde eine ID von 0 haben.

    
Robert Wagner 06.12.2008 02:54
quelle
1

Hängt davon ab, wie der Typ verwendet wird. Es ist oft einfacher für Benutzer des Typs, keinen "undefinierten" Wert zu haben, da Sie keinen speziellen Wert angeben müssen. Aber wenn Sie eine benötigen (weil Werte manchmal in einem Zustand sein müssen, der sonst keiner der aufgezählten Werte ist), dann brauchen Sie einen. Normalerweise speichern Sie keinen speziellen Code, indem Sie zwei Enums anstelle von einem verwenden.

Es ist ein bisschen so, als würde man fragen, ob man Nullable-Typen verwenden darf.

    
Steve Jessop 06.12.2008 02:14
quelle

Tags und Links