2008-10-17 21 views
39

Ich habe festgestellt, dass es in der Regel einen einzelnen Typ oder Namespace gibt, der eine bestimmte Enumeration als Parameter akzeptiert, und daher habe ich diese Enums dort immer definiert. Kürzlich hatte ich einen Kollegen, der eine große Sache darüber machte, wie das eine dumme Sache zu machen ist, und Sie sollten immer einen Enum-Namespace an der Wurzel Ihres Projekts haben, wo Sie jeden Ihrer Enum-Typen definieren.Wo ist der beste Ort, um Enum-Typen zu finden?

Wo ist der beste Ort, um Enum-Typen zu finden?

+2

Anything „best-practice“ im Zusammenhang immer Ihre Mitarbeiter falsch ist, wird subjektiv sein, aber ich denke. Das .NET-Framework enthält keinen Enums-Namespace und das aus gutem Grund. Setzen Sie die Enums in den Namensraum, in dem sie am logischsten sind. (Und wenn es angebracht ist, ja, schachteln Sie sie in einer Klasse.) –

+7

Bis Ihr Kollege sein/ihr Problem erklärte, ist "dumm" nicht wirklich eine Metrik, nach der Sie handeln können. –

+0

So ausgedrückt, der Mitarbeiter ist falsch. Wenn die Lösung viele Projekte hat und die Enums in mehreren Projekten verwendet werden, ist es sinnvoll, sie an einem Ort zu haben. – Bakudan

Antwort

43

Warum Enums anders als andere Typen behandeln? Bewahren Sie sie im selben Namespace auf, in dem sie auch verwendet werden - und nehmen Sie an, dass sie von anderen Klassen verwendet werden, um sie zu Top-Level-Typen in ihren eigenen Dateien zu machen.

Die einzige Art von Typ, den ich ist verklumpen häufig zusammen tun Delegierten - ich Delegates.cs mit einem Bündel von Delegierten Datei manchmal in weniger so mit .NET 3.5 und Func/Aktion, es Ihnen nichts ausmacht..

2

Welche Umgebung?

In .NET Ich normalerweise eine leere Klassendatei erstellen, benennen Sie es in MyEnum oder was auch immer, um anzuzeigen, dass es meine enum hält und nur dort deklarieren.

+0

.NET, aber ich denke, dass das gleiche in C++ gelten würde. – aceinthehole

2

Wenn meine Aufzählung die Möglichkeit hat, jemals außerhalb der Klasse verwendet zu werden, die ich verwenden möchte, erstelle ich eine separate Quelldatei für die Enumeration. Ansonsten werde ich es in die Klasse legen, die ich verwenden möchte.

8

Auch Namespaces sind für die Trennung von Dingen, die logisch zusammengehören. Nicht alle Klassen gehören in denselben Namespace, nur weil sie Klassen sind. Ebenso gehören nicht alle Enums in denselben Namespace, nur weil sie enums sind. Setzen Sie sie mit dem Code, den sie logisch gehören.

1

Ich neige dazu, sie zu definieren, wo ihre Verwendung offensichtlich ist. Wenn ich ein typedef für eine Struktur haben, die Verwendung von es aus irgendeinem Grund macht ...

typedef enum { 
    HI, 
    GOODBYE 
} msg_type; 

typdef struct { 
msg_type type; 
union { 
    int hivar; 
    float goodbyevar; 
    } 
} msg; 
2

Normalerweise finde ich, dass die Aufzählungs um eine einzige Klasse zentriert ist - als MyClassOptions Art der Sache.

In diesem Fall stelle ich das Enum in der gleichen Datei wie MyClass, aber innerhalb des Namespace aber außerhalb der Klasse.

namespace mynamespace 
{ 
    public partial class MyClass 
    { 
    } 
    enum MyClassOptions 
    { 
    } 
} 
4

Ich versuche generell alle meine verschiedenen Typen (Klassen-Schnittstellen und Aufzählungen) zu setzen in ihren eigenen Dateien, unabhängig davon, wie klein sie sind. Es macht es einfach, die Datei, in der sie sich befinden, einfacher zu finden und zu verwalten, besonders wenn Sie nicht in Visual Studio sind und die Funktion "Gehe zur Definition" verfügbar haben. Ich habe festgestellt, dass ich fast jedes Mal, wenn ich einen "einfachen" Typ wie diesen in eine andere Klasse gesetzt habe, es entweder später hinzufüge oder es so wiederverwende, dass es keinen Sinn mehr dafür macht habe eine eigene Datei.

Was den Namespace angeht, hängt es wirklich vom Design dessen ab, was Sie gerade entwickeln. Im Allgemeinen versuche ich, die Konvention von .NET Framework nachzuahmen.

4

Ich versuche alles, was mit einer Klasse in der Klasse verbunden ist. Dazu gehören nicht nur Enums, sondern auch Konstanten. Ich möchte nicht woanders nach der Datei oder Klasse mit den Enums suchen. In einer großen App mit vielen Klassen und Ordnern wäre es nicht immer offensichtlich, wo die Enum-Datei abgelegt werden muss, damit sie leicht zu finden ist.

Wenn die Enumeration in mehreren eng verwandten Klassen verwendet wird, können Sie eine Basisklasse erstellen, sodass die gemeinsamen Typen wie Enums dort gemeinsam genutzt werden.

Natürlich, wenn eine Enum wirklich generisch und weit verbreitet ist, möchten Sie möglicherweise eine separate Klasse für sie zusammen mit anderen generischen Dienstprogrammen erstellen.

4

Ich denke, Sie setzen Enums und Konstanten in der Klasse, die sie verbraucht oder die sie verwendet, um Code-Entscheidungen am meisten zu steuern, und Sie verwenden Code-Vervollständigung, um sie zu finden. Auf diese Weise müssen Sie sich nicht merken, wo sie sind, sie sind mit der Klasse verbunden. Wenn ich zum Beispiel eine ColoredBox-Klasse habe, muss ich nicht darüber nachdenken, wo sie sind. Sie wären Teil von ColoredBox. ColoredBox.Colors.Red, ColoredBox.Colors.Blue usw. I Ich denke an die Enum und Konstante als eine Eigenschaft oder Beschreibung dieser Klasse. Wenn es von mehreren Klassen verwendet wird und keine Klasse die Oberhand behält, ist es angemessen, eine Enum-Klasse oder Konstantenklasse zu haben. Dies folgt Regeln der Kapselung. Isolieren von Eigenschaften aus verschiedenen Klassen. Was, wenn Sie sich entscheiden, den RGB-Wert von Rot in Cirle-Objekten zu ändern, aber , wenn Sie das Rot für ColoredBox-Objekte nicht ändern möchten? Das Einkapseln ihrer Eigenschaften ermöglicht dies.

2

Ich verwende verschachtelte Namespaces für diese. Ich mag sie besser, als die Enumeration in eine Klasse zu schreiben, da außerhalb der Klasse die volle MyClass :: MyEnum-Verwendung verwendet werden muss, selbst wenn MyEnum nicht mit anderen Bereichen kollidiert.

Mit einem verschachtelten Namespace können Sie die "using" -Syntax verwenden. Außerdem werde ich Enums, die sich auf ein bestimmtes Subsystem beziehen, in einer eigenen Datei ablegen, so dass Sie keine Abhängigkeitsprobleme bekommen, wenn Sie die Welt mit einbeziehen müssen, um sie zu verwenden.

So in der ENUM-Header-Datei erhalten Sie:

// MyEnumHeader.h 
// Consolidated enum header file for this dll,lib,subsystem whatever. 
namespace MyApp 
{ 
    namespace MyEnums 
    { 
    enum SomeEnum { EnumVal0, EnumVal1, EnumVal2 }; 
    }; 
}; 

Und dann in der Klasse Header-Datei erhalten Sie:

// MyInterfaceHeader.h 
// Class interfaces for the subsystem with all the expected dependencies. 

#include "MyEnumHeader.h" 

namespace MyApp 
{ 
    class MyInterface 
    { 
    public: 
    virtual void DoSomethingWithEnumParam (MyEnums::SomeEnum enumParam) = 0; 
    }; 
}; 

Oder wie viele Enum-Header-Dateien verwenden, wie sinnvoll ist. Ich mag es, sie von den Klassenheadern getrennt zu halten, damit die Enums an anderer Stelle im System verwendet werden können, ohne die Klassenheader zu benötigen. Wenn Sie sie an einer anderen Stelle verwenden möchten, müssen Sie die Einkapselungsklasse nicht wie bei der Deklaration der Enums innerhalb der Klassen definieren.

Und wie bereits erwähnt, in dem äußeren Code Sie folgende verwenden:

using namespace MyApp::MyEnums; 
Verwandte Themen