【问题标题】:How can a variable typed as an enum take a value that is out of range of its elements?作为枚举类型的变量如何获取超出其元素范围的值?
【发布时间】:2011-08-07 22:43:06
【问题描述】:

谁能向我解释一下这个枚举的成员如何获取0 的值?

public enum EnumLogicalOperator
{
    And = 1,
    Or = 2
}



【问题讨论】:

  • 我对 C# 了解不多——会不会是枚举值为 null?
  • @Matt Ball:不,它不能为空。甚至想到,它得到的价值是0而不是null

标签: c# .net enums default-value


【解决方案1】:

无论何时使用default(EnumLogicalOperator)new EnumLogicalOperator(),您都会得到一个零值。换句话说,枚举类型成员的 默认 值始终为 0。所有枚举都将具有值 0,直到您将它们设置为其他值。

【讨论】:

  • 太好了,谢谢。其实我没想到这是默认值。我专注于“它是如何从价值中提取价值形式的”
  • @Jack:通常的最佳实践是让默认值 (0) 为 Undefined、NotSet、Unknown 等。不要忘记,枚举不限于定义的值。 (EnumLogicalOperator)5 有效。
【解决方案2】:

枚举类型的实例可以从其基础类型的任何合法值创建,即使枚举的“命名”成员没有与该基础值相关联。特别是,看到值0 很常见,因为:

  1. 它是枚举类型的默认值。
  2. 为方便起见,C# 允许您将文字 0 隐式转换为任何枚举类型。

【讨论】:

    【解决方案3】:

    枚举的默认值为0;我相信standard recommendation 是您始终在枚举中包含分配给 0 的内容以解决此问题(根据我的经验,“未知”或“无”都很好用)。

    【讨论】:

      【解决方案4】:

      本页提到:http://msdn.microsoft.com/en-us/library/sbbt4032%28v=vs.80%29.aspx

      枚举 E 的默认值是表达式 (E)0 产生的值

      所以基本上,默认值总是是整数值 0。所以我猜你在这里得到的是 LogicalOperatorWithPreviousRule 从未被分配过值。

      【讨论】:

        【解决方案5】:

        来自C# Language Specification1.10 节,枚举):

        枚举类型的值集 can take on 不受其枚举的限制 成员。特别是,任何价值 枚举的基础类型可以是 强制转换为枚举类型并且是 该枚举的不同有效值 输入。

        另外,4.1.2 节,默认构造函数 指定枚举默认为0

        下载文档,里面有很多有趣的信息:-)

        【讨论】:

          【解决方案6】:

          枚举可以根据其基础类型(在您的情况下为 Int32)具有 any 值。

          EnumLogicalOperator op = (EnumLogicalOperator) 0;
          EnumLogicalOperator op = (EnumLogicalOperator) 100;
          EnumLogicalOperator op = (EnumLogicalOperator) 900000;
          EnumLogicalOperator op = (EnumLogicalOperator) -1;
          
          private EnumLogicalOperator _op; // As a class member, will default to 0
          

          在验证您的输入和处理错误情况时,请务必使用Enum.IsDefined。将 0 作为您的枚举值之一的值通常也是一个好主意。

          【讨论】:

          • 谨慎使用Enum.IsDefined。 Brad Abrams 解释了为什么这可能会导致问题:The danger of over simplification: Enum.IsDefined()
          • 对,问题是当您不是定义枚举的人时,就会假设您将永远知道这些值。在这种情况下,看起来他都定义了枚举 并且 将对所有值进行操作。也忽略了反射问题作为过早的优化。
          • 即使您定义枚举的人也适用。在以后的版本中仍然可以添加新值,这可能会破坏您的代码。除此之外,它是通过反射实现的,因此如果您经常执行它或在假定为轻调用的属性上执行它,这可能是一项非常昂贵的检查。无论如何,我并不是说有问题的代码肯定有问题。在提出使用 Enum.IsDefined 的一揽子建议时,请牢记这一点。
          • 我的观点是,通过添加您自己必须处理的枚举值,您已经破坏了您的代码,并且无论如何都会到处修复/更新。当您不知道更改时,往往会发生版本控制问题。一个可怜的同事可能会发生这种情况,但我仍然不会认为这是一个超出你已经做过的问题。
          【解决方案7】:

          整数变量的默认值为0。因为每个枚举元素的默认底层类型是int,它代表一个整数,所以你的变量的默认值为0。

          documentation 明确表示:

          枚举 E 的默认值是表达式 (E)0 产生的值。


          获得不同默认值的唯一方法是在声明变量时显式初始化它:

          EnumLogicalOperator x = EnumLogicalOperator.Or;
          

          这就是为什么it's generally recommended 0 对应于枚举中的有效元素,因为这将是该类型所有变量的默认值。


          此外,可以将 any 任意整数值分配给类型为枚举的变量。 documentation 警告:

          可以为 meetingDay 分配任意整数值。例如,这行代码不会产生错误: meetingDay = (Days) 42。但是,您不应该这样做,因为隐含的期望是枚举变量将仅保存枚举定义的值之一。为枚举类型的变量分配任意值会带来很高的错误风险。

          C# 语言规范(特别是关于枚举的第 1.10 节)更清楚地说明了这一点:

          枚举类型可以采用的值集不受其枚举成员的限制。特别是,枚举的基础类型的任何值都可以转换为枚举类型,并且是该枚举类型的不同有效值。

          这就是为什么公共框架方法始终验证指定的值是否在该枚举的有效值范围内非常重要的原因。您不能依赖类型检查系统来确保这一点。框架设计指南建议:

          进行参数验证。不要假设枚举参数将在定义的范围内。将任何整数值转换为枚举是合法的,即使该值未在枚举中定义。

          【讨论】:

            【解决方案8】:

            我建议您包含一个值为 0 的成员“未定义”,或者将您的“与”或“或”设为 0 值。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-04-21
              • 1970-01-01
              • 1970-01-01
              • 2021-09-25
              • 2021-06-05
              • 1970-01-01
              • 1970-01-01
              • 2023-03-12
              相关资源
              最近更新 更多