嵌套枚举的替代方案

时间:2013-10-23 16:58:12

标签: c# enums

我正在尝试创建多个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 个答案:

答案 0 :(得分: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)
    {
    }
}

如果您只希望子类型在某些上下文中有效,您还可以使用接受类型为GiftsGraphicsAndDesign的对象的参数。

可悲的是,使用这个解决方案,没有一个好的方法来switch下拉值;您只需使用if / else if个链来检查值。

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

EqualsGetHashCode实现如果没有被覆盖则应该有意义。

如果项目应以某种方式按逻辑顺序排列,则可以实现IComparable