2012-12-17 8 views
6

Diese Diskussion geht es um einen Namen Standardwert: C#: Should the default value of an enum be None or Unknown?C++ Standard-Enumerationswert Nutzung

jedoch große Menge von Menschen, die ich mit vor kurzem als Standard-ENUM-Werten schädlich, unnötig und potenziell führen zu einer schlechten Praxis gesprochen.

Als Beispiel ist folgendes zu beachten:

enum eJobStates 
{ 
    JOB_STATE_INITIALISING, 
    JOB_STATE_PROCESSING, 
    JOB_STATE_DONE 
}; 

es keinen Sinn für einen Job machen würde in etwa JOB_STATE_UNKNOWN zu sein, aber man kann sich vorstellen, dass jede Struktur, die für die Überwachung verwendet werden könnten, der Arbeitsplätze könnte Verwenden Sie einen solchen Wert.

Gibt es Best Practices/Faustregeln bezüglich der Erstellung eines Standardwerts beim Definieren einer Enumeration? Sollten sie wann immer möglich um jeden Preis vermieden werden?

+0

Nun, kann Ihre Überwachungsklasse die Enumeration erweitern, indem Sie einen MONITORING_STATE-Wert hinzufügen? – dchhetri

+0

Ich könnte den Vorschlag nicht vollständig verstehen. In diesem speziellen Beispiel würde MONITORING_STATE aus der Jobperspektive immer noch nicht viel Sinn ergeben und, wie in [link] (http://stackoverflow.com/questions/1804840/extending-enums-in-c) angegeben, kann ich die enum in der Überwachungsklasse (die idealerweise eJobStates als private Variable verwendet). – ellimilial

+1

Ja, mir ist klar, dass man Enums natürlich nicht verlängern kann. monitoring_state war nur ein Name, aber Sie könnten definitiv job_state_unknown verwenden. Was ich vorgeschlagen habe, war, zusätzliche Enum in der Überwachungsklasse hinzuzufügen. Sie können dies tun, indem Sie den letzten Enum-Wert von eJobStates übernehmen und ihm 1 hinzufügen und ihn zum Anfangswert des Enum-Status für die Überwachungsklasse machen. Schließlich vergleichen Sie mit enums nur Ints, die Zustände darstellen. Wenn Sie etwas Konkreteres möchten, können Sie, wie in der Verknüpfung vorgeschlagen, entweder eine Enum-Klasse erstellen oder für jeden Zustand ein Zustandsobjekt erstellen. – dchhetri

Antwort

2

Ein ungültiger Standardwert ist im Grunde eine Variante in Ihrem Design. Das Objekt ist nicht gültig, wenn es erstellt wird. Sie sollten das vermeiden, wenn es vernünftig ist. Auf keinen Fall sollten Sie es "um jeden Preis" vermeiden.

Bei einigen Problemen müssen Sie in einem Variantenzustand beginnen. In diesem Fall haben Sie , um diesen ungültigen Wert mental zu begründen. Wenn Sie es vermeiden, es zu benennen, machen Sie Ihren Code aktiv weniger ausdrucksvoll. Denken Sie darüber nach, was die Kommunikation zwischen Ihnen und der Person betrifft, die den Code später pflegen muss.

Der Umgang mit dem Wind ist ärgerlich. Sie beginnen in einem Variantenzustand, aber wenn es relevant ist, hoffen Sie, dass es keine Variante mehr ist. Die Strategie, die ich bevorzuge, ist es, Benutzern zu erlauben, den Variantenzustand zu ignorieren und einfach zu werfen, wenn ich einen Fehler gemacht habe.

Dies befreit Ihre Benutzer von der Notwendigkeit, über Ihre Varianz nachzudenken, für die es sich zu kämpfen lohnt.

Wenn Sie damit nicht durchkommen, bevorzuge ich es normalerweise, zu sicheren und unsicheren Schnittstellen zu degradieren.

struct Foo { 
    Foo() : val(FooType::INVALID) {} 
    bool get(FooType::EnumValue& val_) const { 
    if (val == FooType::INVALID) 
     return false; 
    val_ = val; 
    return true; 
    } 
    FooType::EnumValue get() const { 
    FooType::EnumValue val_; 
    if (!get(val_)) 
     throw std::logic_error("variant Foo state"); 
    return val_; 
    } 
    FooType::EnumValue get_or_default(FooType::EnumValue def) const { 
    FooType::EnumValue val_; 
    if (!get(val_)) 
     return def; 
    return val_; 
    } 
    FooType::EnumValue val; 
}; 

Diese Arten von Schnittstellen sind gut für Dinge wie Datenbanken, in denen Nullwerte erwartet werden können.

+0

"Denken Sie darüber nach in Bezug auf die Kommunikation zwischen Ihnen und der Person, die den Code später pflegen muss" +1 dafür, zusätzlich zu allem anderen! – xtofl