2013-10-23 158 views
5

我试图创建几个enums,因此给出Dropdown.Category.Subcategory的语法。但是,我一直在阅读,这不是一个好主意。我的选择主要是因为我不能想出任何其他方式来根据类别的选择选择不同的enum值,然后基于enum值选择enum替代嵌套枚举

有没有更好的方法来创建这样的功能?我希望能够轻松识别.Category.Subcategory这两个名称,如果此代码可读,这将是一项奖励。

为了说清楚,我希望能够选择Category,然后选择适当的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

你在读什么,为什么说这不是个好主意?在大多数情况下,枚举不应该嵌套在类中;他们应该处于顶级水平,但这似乎是一个合适的上下文。在大多数情况下,尽管通过它的父类型始终访问枚举只是令人讨厌的。如果它在某种情况下是有益的,那就没问题。 – Servy

+0

你确定你不需要数据库吗? – acfrancis

+0

如果这些枚举只在Dropdown类中使用,那么没有理由不去做你现在正在做的事情。 –

回答

4

创建一个不能从外部继承的类,给它几个内部类,每个类都从它继承。然后添加静态只读变量每个值要代表:

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; 
    } 
} 

在这种情况下,每一个值实际上是Dropdown类型的实例,所以你可以有,也就是说,一个参数的方法接受Dropdown实例。有了枚举,就没有办法说:“我想接受Dropdown类中声明的任何枚举。”

下面是一些例子用法:

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

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

你也可以有一个不接受Gifts型或GraphicsAndDesign的对象,如果你只想要一个子类是在某些情况下有效的参数。

不幸的是,使用这个解决方案没有好的办法来switch下拉值;您必须使用if/else if链来检查值。

实例字符串值的使用可能不是必需的(请参阅没有它的版本的第一个修订版本),但它能够有一个有意义的字符串值(或其他类型的值;您可以将一个整数,一个字节或任何与每个枚举值关联)。

如果没有被覆盖,EqualsGetHashCode实现应该是有意义的。

如果项目应按照某种方式进行逻辑排序,您可以实施IComparable,如真正的枚举。

+0

比我的+1更好的解决方案。我正在考虑删除我的;-( – Harrison

+0

不得不说,这真的很高雅。非常感谢,我更喜欢这个! –

+0

小问题,这个语法是有效的代码,因为继承了'Dropdown':'Dropdown .Gifts.GraphicsAndDesign.Gifts.GraphicsAndDesign'等。 –