何时使用枚举,何时用静态成员替换它们?

sta*_*ica 33 c# polymorphism enums static-members

最近发生了以下(样本)枚举......

enum Color
{
    Red,
    Green,
    Yellow,
    Blue
}
Run Code Online (Sandbox Code Playgroud)

......可以用看似更加类型安全的类替换:

class Color
{
    private Color() { }

    public static readonly Color   Red      = new Color();
    public static readonly Color   Green    = new Color();
    public static readonly Color   Yellow   = new Color();
    public static readonly Color   Blue     = new Color();
}
Run Code Online (Sandbox Code Playgroud)

对于"类型安全",我的意思是如果Color是枚举,则以下语句将起作用,但如果Color是上述类则不行:

var nonsenseColor = (Color)17;    // works if Color is an enum
Run Code Online (Sandbox Code Playgroud)

两个问题:

1)这种模式是否有广泛接受的名称(用类型安全类替换枚举)?

2)在哪种情况下应该使用枚举,什么时候更合适?

Chr*_*aas 27

枚举非常适合轻量级状态信息.例如,您的颜色枚举(不包括蓝色)将有助于查询交通信号灯的状态.真正的颜色以及整个颜色概念及其所有行李(阿尔法,颜色空间等)都无关紧要,只有哪个状态是光线.另外,稍微改变你的枚举以代表交通灯的状态:

[Flags()]
public enum LightColors
{
    unknown = 0,
    red = 1,
    yellow = 2,
    green = 4,
    green_arrow = 8
}
Run Code Online (Sandbox Code Playgroud)

当前的灯状态可以设置为:

LightColors c = LightColors.red | LightColors.green_arrow;
Run Code Online (Sandbox Code Playgroud)

并询问:

if ((c & LightColors.red) == LightColors.red)
{
    //Don't drive
}
else if ((c & LightColors.green_arrow) == LightColors.green_arrow)
{
    //Turn
}
Run Code Online (Sandbox Code Playgroud)

静态类颜色成员将能够支持此多状态而无需额外功能.

但是,静态类成员对常用对象很有用.该System.Drawing.Color成员是很好的例子,因为它们代表一个已知的名字颜色有模糊的构造函数(除非你知道你的十六进制的颜色).如果将它们实现为枚举,则每次要将值用作颜色时,都必须执行以下操作:

colors c = colors.red;
switch (c)
{
    case colors.red:
        return System.Drawing.Color.FromArgb(255, 0, 0);
        break;
    case colors.green:
        return System.Drawing.Color.FromArgb(0,255,0);
        break;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果你有一个枚举并发现你经常做一个switch/case/if/else /无论派生一个对象,你可能想要使用静态类成员.如果你只是查询某事的状态,我会坚持使用枚举.此外,如果您必须以不安全的方式传递数据,枚举可能比对象的序列化版本更好.

编辑: @stakx,我认为你偶然发现一些重要的东西,以回应@Anton的帖子,这很复杂,或者更重要的是,谁是复杂的?

从消费者的角度来看,我非常希望System.Drawing.Color静态类成员不必编写所有这些.然而,从制作人的角度来看,必须编写所有这些内容将是一件痛苦的事.因此,如果其他人将使用您的代码,您可能会通过使用静态类成员来节省很多麻烦,即使它可能需要10倍的时间来编写/测试/调试.但是,如果只是你,你可能会发现根据需要使用枚举和转换/转换更容易.

  • 枚举很棒,我们应该让枚举再次伟大。 (2认同)