【问题标题】:How to prevent enum constructors如何防止枚举构造函数
【发布时间】:2018-01-09 15:57:33
【问题描述】:

我很惊讶,但枚举可以使用 C# 中的构造函数创建。 例如,我有枚举:

public enum Color
{
    White = 1,
    Red = 2
}

然后可以这样创建:

var color = new Color();

而且值会是0,实际上不是有效的枚举值。

那么,我们能以某种方式禁止枚举构造函数吗?任何其他想法如何避免这种情况?

谢谢。

【问题讨论】:

  • var color = (Color)125; 也是完全合法的。读取枚举变量时必须手动检查值是否有效...
  • msdn.microsoft.com/en-us/library/ms182149.aspx 为什么需要给非标志枚举赋值?
  • 0 是任何值类型的默认值,无论它是否有效且无法更改。你用枚举做什么?也许如果我们有更多的上下文,我们可以提出一个替代方案。
  • 作为解决此问题的一种 hacky 方法,您可以使用代码分析器来获取 Enum 构造函数的错误
  • 你不能用枚举做到这一点,但你可以创建自己的自定义类(“类型安全枚举”)并限制其可能的值。

标签: c# enums


【解决方案1】:

那么,我们能否以某种方式禁止枚举构造函数?

没有。问题与构造函数本身并不严格相关:(Color)0 也是有效的,因为底层类型可以具有值 0

还有什么办法可以避免这种情况?

不,这基本上是一个更广泛的问题。防止这种情况发生的唯一方法是检查输入值的有效性。

根据Code Analysis,您应该始终拥有0 枚举值。

【讨论】:

  • 您甚至不需要强制转换 0 将其分配给枚举。
  • @MatthewWatson 同意,否则代码示例将难以理解。
【解决方案2】:

public enum Color 实际上是枚举的完整声明的缩写形式,即public enum Color : int

枚举 always 具有底层的基本类型,从技术上讲,它只是该类型的变量。默认情况下,此类型为 32 位整数,这意味着任何 32 位整数都可以分配给这样的枚举。

实际的枚举定义只是该类型的命名成员,以便在编程中使用,允许您更改甚至完全忽略底层值,而无需更改代码。

但在内部,您类型的所有枚举 Color(顺便说一下,这个名字很糟糕)只是 Int32 值,而 as Anders Forsgren pointed out 与任何其他 Int32 值一样,它们在数组和任何类型的全局值中默认为 0变量。这也是官方指南建议始终在枚举中放置 0 定义的原因。

【讨论】:

    【解决方案3】:

    不,一般来说没有办法避免它。您可以让静态分析器发出警告,但它不能解决枚举只是一个数字的潜在问题,因此它的值可以是 123。更常见的是它的值为零(例如,如果你新建它,或不分配)。

    要更清楚地看到问题,请考虑以下问题:

    var colors = new Color[100];
    

    colors[0] 现在是什么?它是零,就像任何未初始化的数字一样。因此,枚举允许您为值命名 - 它确实保证该类型的变量使用这些命名值之一。

    一个好的最佳实践是在您的枚举中始终有一个为零的名称值(通常在这种情况下,它会被称为“无”、“未初始化”、“未设置”或类似名称)。一旦你有了它,未初始化的值就有意义了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 2020-10-28
      相关资源
      最近更新 更多