2013-10-23 14 views
5

Ich versuche, mehrere als solche zu erstellen, die die Syntax Dropdown.Category.Subcategory gibt. Ich habe jedoch gelesen, dass dies keine so gute Idee ist. Meine Wahl dafür war hauptsächlich, weil ich keine andere Möglichkeit finden konnte, verschiedene enum Werte auszuwählen, abhängig von der Wahl der Kategorie, und dann die Wahl der Unterkategorie abhängig von den enum Werten basierend auf den enum Werten.Alternative zu Verschachtelung enums

Gibt es eine bessere Möglichkeit, solche Funktionen zu erstellen? Ich würde es vorziehen, sowohl die .Category als auch die .Subcategory Namen leicht identifizieren zu können, und es wäre ein Bonus, wenn dieser Code lesbar wäre.

Nur um es klar zu machen, möchte ich in der Lage sein, die Category wählen, dann haben Sie eine entsprechende Subcategory Auswahl.

public class Dropdown 
{ 
    public enum Gifts 
    { 
     GreetingCards, 
     VideoGreetings, 
     UnusualGifts, 
     ArtsAndCrafts, 
     HandmadeJewelry, 
     GiftsforGeeks, 
     PostcardsFrom, 
     RecycledCrafts, 
     Other 
    } 
    public enum GraphicsAndDesign 
    { 
     CartoonsAndCaricatures, 
     LogoDesign, 
     Illustration, 
     EbookCoversAndPackages, 
     WebDesignAndUI, 
     PhotographyAndPhotoshopping, 
     PresentationDesign, 
     FlyersAndBrochures, 
     BusinessCards, 
     BannersAndHeaders, 
     Architecture, 
     LandingPages, 
     Other 
    } 
} 
+1

Was hast du gelesen, und warum hat es gesagt, dass das keine gute Idee war? In den meisten Fällen sollten Enums nicht in Klassen verschachtelt sein. Sie sollten auf einer Top-Ebene sein, aber das scheint ein angemessener Kontext zu sein. In den meisten Fällen ist es jedoch nervig, immer auf eine Enumeration durch den übergeordneten Typ zuzugreifen. Wenn es in einem bestimmten Kontext nützlich ist, dann ist das in Ordnung. – Servy

+0

Sind Sie sicher, dass Sie keine Datenbank benötigen? – acfrancis

+0

Wenn diese Aufzählungen nur innerhalb der Dropdown-Klasse verwendet werden, gibt es keinen Grund, nicht das zu tun, was Sie gerade tun. –

Antwort

4

Erstellen Sie eine Klasse, die nicht von extern vererbt werden kann, geben Sie ihr mehrere innere Klassen, die jeweils davon ausgehen. Dann statisch für jeden der Werte nur Variablen Lese hinzufügen, die Sie darstellen möchten:

public class Dropdown 
{ 
    private string value; 

    //prevent external inheritance 
    private Dropdown(string value) 
    { 
     this.value = value; 
    } 

    public class Gifts : Dropdown 
    { 
     //prevent external inheritance 
     private Gifts(string value) : base(value) { } 

     public static readonly Dropdown GreetingCards = 
      new Gifts("GreetingCards"); 
     public static readonly Dropdown VideoGreetings = 
      new Gifts("VideoGreetings"); 
     public static readonly Dropdown UnusualGifts = 
      new Gifts("UnusualGifts"); 
     public static readonly Dropdown ArtsAndCrafts = 
      new Gifts("ArtsAndCrafts"); 
    } 
    public class GraphicsAndDesign : Dropdown 
    { 
     //prevent external inheritance 
     private GraphicsAndDesign(string value) : base(value) { } 

     public static readonly Dropdown CartoonsAndCaricatures = 
      new GraphicsAndDesign("CartoonsAndCaricatures"); 
     public static readonly Dropdown LogoDesign = 
      new GraphicsAndDesign("LogoDesign"); 
     public static readonly Dropdown Illustration = 
      new GraphicsAndDesign("Illustration"); 
    } 

    public override string ToString() 
    { 
     return value; 
    } 
} 

In diesem Fall jeder einzelne Wert ist eigentlich eine Instanz vom Typ Dropdown, so könnten Sie haben, sagen wir, einen Parameter auf ein Verfahren das akzeptiert eine Dropdown Instanz. Mit Enums gibt es keine Möglichkeit zu sagen: "Ich möchte alle in der Klasse Dropdown deklarierten Enums akzeptieren." Hier

ist ein Beispiel einer Nutzung:

public static void UseDropdown(Dropdown type) 
{ 
    if (type is Dropdown.Gifts) 
    { 
     if (type == Dropdown.Gifts.GreetingCards) 
     { 
      DoStuff(); 

     } 
    } 
    else if (type is Dropdown.GraphicsAndDesign) 
    { 
    } 
} 

Sie könnten auch einen Parameter haben, die ein Objekt vom Typ akzeptiert Gifts oder GraphicsAndDesign, wenn Sie nur ein Untertyp gültig zu sein in einem bestimmten Kontext wollen.

Leider gibt es mit dieser Lösung keinen guten Weg zu switch auf einem Dropdown-Wert; Sie müssen nur if/else if Ketten verwenden, um die Werte zu überprüfen.

Die Verwendung eines Wert Instanz String ist möglicherweise nicht erforderlich (für eine Version, ohne dass die erste Revision sehen), aber es kann sehr hilfreich sein, um einen sinnvollen Zeichenfolge-Wert (oder eine andere Art von Wert haben, können Sie Ordnen Sie jedem Aufzählungswert eine ganze Zahl, ein Byte oder was auch immer zu). Die Equals und GetHashCode Implementierungen sollten sinnvoll sein, wenn sie nicht überschrieben werden.

Sie können IComparable implementieren, wenn die Elemente logisch wie echte Enums logisch sortiert sein sollen.

+0

Viel bessere Lösung als meine +1.Ich denke daran, meine zu löschen ;-( – Harrison

+0

Ich muss sagen, das ist auch sehr elegant. Vielen Dank, ich bevorzuge das! –

+0

Kleines Problem, diese Syntax ist gültiger Code, wegen der Vererbung zu 'Dropdown':' Dropdown .Geschenke.GraphicsAndDesign.Gifts.GraphicsAndDesign' usw. –