枚举和常量。哪个用的?

时间:2009-03-05 07:04:36

标签: c# language-agnostic enums

我正在对枚举进行一些阅读,发现它们与声明常量非常相似。我怎么知道何时使用常量而不是枚举,反之亦然。使用枚举有哪些优点?

8 个答案:

答案 0 :(得分:81)

如果要定义某些值可以使用的值,请使用枚举。颜色就是一个明显的例子:

public enum Colour
{
    White,
    Red,
    Blue
}

或者可能是一组可能的事情: (示例我从here偷走了,因为我很懒)

[FlagsAttribute]
enum DistributedChannel
{
  None = 0,
  Transacted = 1,
  Queued = 2,
  Encrypted = 4,
  Persisted = 16,
  FaultTolerant = Transacted | Queued | Persisted
}

常量应该是单个值,例如PI。没有一系列PI值,只有PI。

答案 1 :(得分:27)

其他答案缺少的是枚举有一个整数基类型。您可以将默认值从int更改为除char之外的任何其他整数类型:

enum LongEnum : long {
    foo,
    bar,
}

您可以显式地和隐式地转换为基类型,这在switch语句中很有用。请注意,即使枚举没有具有适当值的成员,也可以将基类型的任何值强制转换为枚举。因此,始终使用开关中的默认部分是个好主意。 BTW,.NET本身甚至允许浮点值枚举,但你不能用C#定义它们,虽然我认为你仍然可以使用它们(交换机除外)。

此外,使用枚举可以提供更多的类型安全性。如果您打算使用例如int常量作为方法参数,然后我可以使用任何int值调用该方法。当然,通过铸造也可以使用枚举,但不会偶然发生。更糟糕的是混淆参数顺序的可能性。

void method(int a, int b) {...}

如果常量A只能进入a而常量B只能进入b,那么使用两种不同的枚举类型将会在编译过程中发现任何误用。

答案 2 :(得分:19)

常量是一种语言特性,它表示变量不会改变值(因此编译器可以围绕该知识进行优化),其中枚举是特定类型。

常量可以是任何数据类型,但枚举是枚举。

我在任何可以提供多种选项的地方使用枚举,并希望提高代码的可读性。即,您可以将跟踪级别设置为值为0,1,2的int或作为错误,警告和信息的枚举。

Enum还可以用作按位运算符,即FontStyle.Bold | FontStyle.Italic会为您提供粗体和斜体字体。

答案 3 :(得分:8)

除了罗伯特的回答:

  1. 对一组有限的命名值使用enum。您并不真正关心每个符号背后的数值(但您仍然可以强加它们,例如,为了与遗留系统兼容)。

  2. Robert:是的,Enum可以用作位字段。使用Flags属性(并确保枚举的成员具有合适的数值)。

答案 4 :(得分:3)

C#常量类似于变量,因为它为值提供了定义的名称。但是,常量与标准变量不同,因为一旦定义,分配给常量的值就永远不会改变。常量的主要好处是可以帮助创建自我记录代码,并允许在一个地方声明键值,如果需要更新值并重新编译软件,则可以轻松维护。

而枚举器列表对于定义序列和状态非常有用,特别是当这些状态有自然进展时。这是因为列表中的每个常量都可以使用其名称或值进行格式化和比较。枚举也可用于定义一组有限的有效值。

答案 5 :(得分:1)

使用enum而不是const时,我发现很方便的一件事是您可以遍历enum中的值,而使用const则很难值。

答案 6 :(得分:0)

如果需要基于整数的值,请使用枚举。 如果您需要基于字符串的值,请使用带有常量的结构。

当你有类似的东西

class x
{
    public string string_value {get;set;}
    publi int int_value  {get;set;}
}

x model = new x();
model.string_value  = struct.some_value;
model.int_value = enum.some_value;

答案 7 :(得分:0)

If you have a set of predefined choices which is not supposed to change (i.e adding more choices etc.) than use enum otherwise consts. Consider the following:
public class Math
{
    enum Command {none = 0, add =1, subtract = 2} 
    const int none =0, add=1,subtract =2;
    public virtual int Operate(int a, int b, Command command) 
    {
        if (command == Command.add) return a+b;
        if(command == Command.subtract) return a-b;
        return a;
    }
    public virtual int Operate(int a, int b, int command) 
    {
        if (command == add) return a+b;
    if(command==subtract) return a-b;
        return a;
    }
}`

class Math1: Math
{
    public override Operate(int a, int b, int command)
    {
        if(command<3) return base.Operate(a, b, command)
        if(command =3) return a*b;
        if(command==4) return a/b;
        return a;
    }
}

因此使用 const 可以允许您传递未在 const 声明中定义的参数值,即 3 表示乘法,4 表示除法。这是好是坏取决于您的逻辑有时允许用户传递任意值并收到意外结果是不明智的。