C# 枚举和常量。什么时候用哪个?

C# 枚举和常量。什么时候用哪个?,c#,language-agnostic,enums,C#,Language Agnostic,Enums,我读了一些关于枚举的书,发现它们与声明常量非常相似。我如何知道何时使用常量而不是枚举,或者反之亦然。使用枚举的一些优点是什么?常量是一种语言功能,它表示在枚举是特定类型的情况下,变量不会改变值(因此编译器可以围绕该知识进行优化) 常量可以是任何数据类型,但枚举是枚举 我在任何地方使用枚举,在那里您可以有许多选项,并希望提高代码的可读性。i、 e.您可以将跟踪级别作为值为0、1、2的int或作为错误、警告和信息的枚举 枚举还可以用作位运算符,即FontStyle.Bold | FontStyle.

我读了一些关于枚举的书,发现它们与声明常量非常相似。我如何知道何时使用常量而不是枚举,或者反之亦然。使用枚举的一些优点是什么?

常量是一种语言功能,它表示在枚举是特定类型的情况下,变量不会改变值(因此编译器可以围绕该知识进行优化)

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

我在任何地方使用枚举,在那里您可以有许多选项,并希望提高代码的可读性。i、 e.您可以将跟踪级别作为值为0、1、2的int或作为错误、警告和信息的枚举


枚举还可以用作位运算符,即FontStyle.Bold | FontStyle.Italic将提供粗体和斜体字体。

当您要定义某个值的范围时,请使用枚举。颜色是一个明显的例子,例如:

public enum Colour
{
    White,
    Red,
    Blue
}
或者一系列可能的事情,比如: (我偷懒时偷的例子)

常量应该是一个值,比如PI。没有PI值的范围,只有PI

其他要考虑的是:

  • 答:常量不一定表示常量之间的关系,而枚举表示某些内容可以是枚举定义的集合之一
  • b:当用作参数时,定义的枚举可以帮助您进行类型检查。常量只是值,所以它们不提供任何额外的语义信息

除了罗伯特的回答:

  • 将枚举用于有限的命名值集。您并不真正关心每个符号后面的数值(但您仍然可以强制使用它们,例如,为了与传统系统兼容)

  • 罗伯特:是的,枚举可以用作位字段。使用该属性(并确保枚举的成员具有合适的数值)

  • C#常量与变量类似,因为它为值提供了定义的名称。但是,常数不同于标准变量,因为一旦定义,分配给常数的值就永远不能更改。常量的主要好处是帮助创建自文档化代码,并允许在单个位置声明键值,从而在需要更新值和重新编译软件时易于维护


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

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

    enum LongEnum : long {
        foo,
        bar,
    }
    
    可以显式地从基类型强制转换为基类型,也可以隐式地从基类型强制转换为基类型,这在switch语句中很有用。请注意,可以将基类型的任何值强制转换为枚举,即使该枚举没有具有适当值的成员。因此,在开关中始终使用默认部分是一个好主意。顺便说一句,.NET本身甚至允许浮点值枚举,但您不能在C#中定义它们,尽管我认为您仍然可以使用它们(在switch中除外)

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

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

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

    当使用
    enum
    而不是
    const
    时,我发现有一件事很方便,那就是可以迭代
    枚举中的值,使用
    const
    值要困难得多。

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

    当你有类似

    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;
    
    如果您有一组预定义的选项,并且这些选项不应该更改(即添加更多选项等),则使用enum或conss。考虑以下事项:
    公共课数学
    {
    枚举命令{none=0,add=1,subtract=2}
    const int none=0,add=1,subtract=2;
    公共虚拟整数操作(整数a、整数b、命令)
    {
    if(command==command.add)返回a+b;
    如果(command==command.subtract)返回a-b;
    返回a;
    }
    公共虚拟int操作(int a、int b、int命令)
    {
    if(command==add)返回a+b;
    if(command==subtract)返回a-b;
    返回a;
    }
    }`
    数学一班:数学
    {
    公共超控操作(int a、int b、int命令)
    {
    
    if(commandsee)另请参见Java的类似问题(答案大多也适用于C)。如果您在枚举上大量使用
    .ToString()
    ,使用具有常量字符串的类时的任何值,该类的外观和行为类似于枚举,但绕过了对
    ToString()的调用,该怎么办
    ?等等,我想我回答了我自己的问题。该示例中的代码不起作用:您必须将输入作为一个字符串,这不会真正像一个枚举。为什么您不能只使用带有常量颜色的静态类颜色而不是枚举?有什么区别?简而言之
    类型安全性“
    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;
    
    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;
        }
    }