2013-10-23 17 views
5

Sto provando a creare più enums come tale, che fornisce la sintassi di Dropdown.Category.Subcategory. Tuttavia, ho letto che questa non è una buona idea. La mia scelta per questo era principalmente perché non riuscivo a pensare a nessun altro modo per selezionare diversi valori enum a seconda della scelta della categoria, e quindi la scelta della sottocategoria è soggetta allo enum selezionato in base ai valori enum.Alternativa alle enumerazioni

C'è un modo migliore per creare tale funzionalità? Preferirei essere in grado di identificare facilmente entrambi i nomi .Category e .Subcategory e sarebbe un vantaggio se questo codice fosse leggibile.

Giusto per chiarire, voglio essere in grado di scegliere il Category, quindi avere una selezione appropriata Subcategory.

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

Cosa stavi leggendo e perché ha detto che non era una buona idea? Nella maggior parte dei casi le enumerazioni non dovrebbero essere annidate nelle classi; dovrebbero essere al livello più alto, ma questo sembra un contesto abbastanza appropriato. Nella maggior parte dei casi però è solo fastidioso accedere a un enum tramite il suo tipo genitore per tutto il tempo. Se è utile in un certo contesto, allora va bene. – Servy

+0

Sei sicuro di non aver bisogno di un database? – acfrancis

+0

Se queste enumerazioni vengono utilizzate solo nella classe Dropdown, non c'è motivo di non fare ciò che si sta facendo attualmente. –

risposta

4

Creare una classe che non può essere ereditata da esternamente, dargli diverse classi interne, ognuna che si estende da esso. Quindi aggiungere statiche di lettura uniche variabili per ciascuno dei valori che si vuole rappresentare:

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 questo caso ogni singolo valore è in realtà un'istanza di tipo Dropdown, quindi si potrebbe avere, ad esempio, un parametro a un metodo che accetta un'istanza Dropdown. Con l'enumerazione non c'è modo di dire: "Voglio accettare qualsiasi enumerazione dichiarata nella classe Dropdown".

Ecco alcuni esempio di utilizzo:

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

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

Si potrebbe anche avere un parametro che accetta un oggetto di tipo Gifts o GraphicsAndDesign, se si desidera solo un sottotipo di essere valido in un certo contesto.

Purtroppo, utilizzando questa soluzione non c'è un buon modo per switch su un valore dropdown; devi solo usare le catene if/else if per controllare i valori.

L'utilizzo di un valore di stringa di istanza potrebbe non essere richiesto (vedere la prima revisione per una versione senza di essa) ma può essere molto utile poter avere un valore stringa significativo (o un altro tipo di valore; associare un numero intero, un byte o qualsiasi cosa con ciascun valore di enumerazione).

Le implementazioni Equals e GetHashCode devono essere significative se lasciate senza essere sovrascritte.

È possibile implementare IComparable se gli articoli devono essere ordinati in modo logico in qualche modo, come le enumerazioni reali.

+0

Soluzione molto migliore della mia +1..! Sto pensando di eliminazione miniera ;-( – Harrison

+0

Devo dire, questo è davvero troppo elegante Grazie mille, preferisco questo –

+0

Piccolo problema, questa sintassi è codice valido, a causa dell'eredità a 'Dropdown':' discesa .Gifts.GraphicsAndDesign.Gifts.GraphicsAndDesign', ecc. –

Problemi correlati