在设计模式中替代枚举

neg*_*nbe 4 .net c# enums design-patterns

考虑base具有enum类似类型的基础组件的情况

public enum ItemState = { red, green, blue };
Run Code Online (Sandbox Code Playgroud)

我在其他程序集中使用此基本程序集Project_1,Project_2依此类推.

他们每个都做一些特定的事情,并需要项目特定的状态,如{grey, black, white, ...}in Project_1{brown, transparent, ...}in Project_2.

Project_1不允许使用(如果可能的话甚至可以看到){brown, transparent, ...}.同样,Project_2不能使用{grey, black, white, ...}.

我知道"部分枚举"不存在 - 那么这个任务的建议设计模式是什么?

Ren*_*ogt 6

由于枚举不能继承,一个解决方案可能是使用具有静态常量成员的类,如下所示:

public class ItemState
{
    protected ItemState() { }

    public static ItemState red { get; } = new ItemState();
    public static ItemState green { get; } = new ItemState();
    public static ItemState blue { get; } = new ItemState();
}
Run Code Online (Sandbox Code Playgroud)

然后在你的Project_1你可以派生自己的类:

public class ItemState_1 : ItemState
{
    public static ItemState grey { get; } = new ItemState_1();
    public static ItemState black white { get; } = new ItemState_1();
}
Run Code Online (Sandbox Code Playgroud)

并在 Project_2

public class ItemState_2 : ItemState
{
    public static ItemState brown { get; } = new ItemState_2();
    public static ItemState transparent white { get; } = new ItemState_2();
}
Run Code Online (Sandbox Code Playgroud)

这可能不是最舒服的方式,但我现在能想到的最好的方式.

你可以像这样使用它们:

ItemState project1State = ItemState_1.grey;

if (project1State == ItemState_1.grey)
   // do something
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但不幸的是这些价值不能用于switch/case声明.这可以通过适当的ToString()实现来解决,可以使用字符串文字switch/case.但这当然会为这些类/属性定义添加更多代码.


Sze*_*zer 5

我有点晚了,但这里是 Rene 答案的“增强”版本(现在带有隐式转换!):

public class ColorEnum
{
    protected readonly string Name;
    protected readonly Color Value;

    public static readonly ColorEnum Red = new ColorEnum(Color.Red, "Red");
    public static readonly ColorEnum Green = new ColorEnum(Color.Green, "Green");
    public static readonly ColorEnum Blue = new ColorEnum(Color.Blue, "Blue");

    protected ColorEnum(Color value, string name)
    {
        Name = name;
        Value = value;
    }

    public override string ToString()
    {
        return Name;
    }

    public static implicit operator Color(ColorEnum @enum)
    {
        return @enum.Value;
    }

    public static implicit operator string(ColorEnum @enum)
    {
        return @enum.Name;
    }
}

public class AnotherColorEnum : ColorEnum
{
    public static readonly ColorEnum Grey = new AnotherColorEnum(Color.Gray, "Grey");
    public static readonly ColorEnum Black = new AnotherColorEnum(Color.Black, "Black");
    public static readonly ColorEnum White = new AnotherColorEnum(Color.White, "White");

    protected AnotherColorEnum(Color value, string name) : base(value, name)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以像这样使用你的“枚举”:

    var color = ColorEnum.Red;
    var anothercolor = Color.Red;
    if (color == anothercolor)
    {
            //DoSomething
    }
Run Code Online (Sandbox Code Playgroud)

或者像这样:

    var color = ColorEnum.Red;
    var anothercolor = "Red";
    if (color == anothercolor)
    {
            //DoSomething
    }
Run Code Online (Sandbox Code Playgroud)