为什么要为枚举声明数值?

时间:2011-07-29 18:20:53

标签: .net enums

我经常看到Simple(非Flags)枚举声明如下:

enum Something
{
    Thingy = 1,
    Thangamijig = 2,
    Whatsit = 3
}

为什么要包含可选的数值?这被认为是最佳做法吗?

MSDN guidelines for enum design似乎没有解释这样做的原因。

我刚才看到了一个潜在的答案:是否要确保包含枚举实例的先前序列化对象不会变为无效或者如果要修改枚举(例如通过重新排序值或插入新值)而改变其含义值)?

这看起来似乎有道理。还有其他原因吗?

6 个答案:

答案 0 :(得分:7)

如果您要在外部保存这些值(如数据库)并希望将其值映射回代码,这一点非常重要。

如果未明确指定,则将在编译时按顺序设置它们。


例如:

enum Something
{
    Thingy,
    Thangamijig,
    Whatsit
}

所以Thingy == 0Thanamijig == 1Whatsit == 2

使用此枚举并将其保存到数据库一段时间,然后其他一些开发人员找到Something的新用法并更改它......很糟糕:

enum Something
{
    Whosits,
    Thingy,
    Thangamijig,
    Whatsit
}

现在Thingy == 1Thanamijig == 2Whatsit == 3,您不再拥有正确的映射。

这只是一种未明确定义每个枚举值映射到的内容会导致大问题的情况。


<强> enum definition on MSDN

枚举元素的默认基础类型是int。默认情况下,第一个枚举数的值为0,每个连续枚举数的值增加1.例如:

enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};

在此枚举中,Sat为0,Sun为1,Mon为2,依此类推。枚举器可以使用初始值设定项来覆盖默认值。例如:

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

在此枚举中,元素序列被强制从1而不是0开始。

答案 1 :(得分:4)

能够分配特定值对于与无法访问C#中定义的类型的其他系统的互操作性非常有用。

例如,COM程序或外部Web服务可以为您选择在C#中表示为枚举的属性定义某些数值。

答案 2 :(得分:3)

就像你先说的那样,最重要的原因是要确保当你改变枚举的顺序时,你没有破坏任何东西。

默认情况下,枚举以0开头,因此如果您有应该具有某些值的变量,则应该具有数值。有时您会看到人们使用第一项作为无,因为它有0值。

使用数字的另一个原因是,如果您使用的是Flags,那么您没有选项,则必须使用值

[Flags]
enum Days2
{
    None = 0x0,
    Sunday = 0x1,
    Monday = 0x2,
    Tuesday = 0x4,
    Wednesday = 0x8,
    Thursday = 0x10,
    Friday = 0x20,
    Saturday = 0x40
}
class MyClass
{
    Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}

答案 3 :(得分:1)

通常在与其他代码连接时。有时硬件具有预定义的枚举值。

有时人们将它们用作标志,值为0,1,2,4 ......然后它们可以一起进行OR运算。稍后可以针对枚举测试int。

答案 4 :(得分:1)

想想更大的数据库。

假设你有一个常量字符串数组,有250个字符串。

但是在代码的某些部分,你并不真的想要使用所有这些字符串,例如只是最后3个字符串。
此功能允许您这样做:

enum LastThree
{
    Thingy = 247,
    Thangamijig = 248,
    Whatsit = 249
}

答案 5 :(得分:1)

当你在某处存储枚举值时,这很重要,这可能是数据库,配置文件等......

想象一下,你最初有这样的枚举

enum TransactionType
{
  Debt,
  Deposit
}

并将ClientA的TransactionType存储为数据库中的TransactionType.Deposit int value 1 )。

后来,另一位开发人员添加了新类型,因此enum现在看起来像

enum TransactionType
{  
  NotAssigned,
  Debt,
  Deposit
}

因此,当应用程序从数据库读取ClientA的事务类型( int == 1 )时,它变为TransactionTYpe.Debt

ClientA会感到困惑,因为在线系统中他会看到他有债务而不是存款。

要避免此类问题,您应该添加初始值。