18

在 C# 中将“0”作为枚举的默认值有什么意义?如果我声明以不同数字开头的枚举:

enum Color
{
   Blue = 1,
   Green,
   Red,
}

然后var color = default(Color)- 将返回“0”。我希望看到最小值。如果枚举的每个成员都对应于某个特定数字并且“0”不是有效值,则此行为可能会导致问题。

4

8 回答 8

14

所有值类型(包括枚举)的默认值是按位 0。因此这意味着 0 始终是枚举的可能值,即使它没有明确定义。

这是规范:默认值表

编辑:有关更多详细信息,请查看 MSDN 的枚举类型 - enum

enum 是一种特殊的类型,它派生自其他值类型(这通常是不可能的),但表现为其支持类型的值类型。枚举只能使用一些整数值作为支持类型。

注意:正如@a​​rchil 指出的那样,枚举值可能包含任何支持类型的值,而与枚举本身枚举的常量列表无关。对于标有“FlagsAttribute”的枚举,这种行为通常是预期的,但对于普通枚举,它可能不直观。

于 2012-05-24T17:29:13.647 回答
10

我们只能推测为什么.NET 框架的某个方面是以某种方式设计的。对于最直接的解释,我想强调一下 MSDN 文档中的这句话:

枚举是一组命名常量,其基础类型是除 Char 之外的任何整数类型。如果没有显式声明基础类型,则使用 Int32。

请注意,.NET 枚举本质上是整数类型的扩展。整数类型的默认值为 0,因此枚举继承该行为是合理的(如果在您说明的情况下有些不便)。

于 2012-05-24T17:50:45.350 回答
7

枚举总是有可能具有不存在的价值。这就是Enum.IsDefined 方法存在的原因。

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

于 2012-05-24T17:30:02.560 回答
3

正如迄今为止在多个答案中所述,任何固定大小的数据结构的“默认”值都是 0。结构内存的大小设置为零,这被认为是“默认”。现在,如果您想为枚举定义自己的“默认”值,您有多种选择。最简单的方法是编写自己的函数来为您提供“最小有效枚举”

private E GetDefaultEnum<E>()
{
    return (E)(Enum.GetValues(typeof(E)).Cast<E>().Min<E>());
}

用法:

enum Color
{
   Blue = 1,
   Green,
   Red,
}

Color defaultColor = GetDefaultEnum<Color>();
MessageBox.Show(defaultColor.ToString()); // "Blue"

您显然可以更改确定“默认”值的方式,但这种方式似乎最适合您的需求。

于 2012-05-24T18:15:53.817 回答
1

为什么 0 是默认枚举值?易于运行时实施。任何值类型的默认值都是按位 0,并且大概是一个空引用由按位 0 表示。因此,要初始构造一个具有其默认值的对象,我们只需要知道它的大小即可;运行时不需要知道或处理有关对象结构的任何内容。类似地,预定义的值类型构造函数只能用零填充内存范围。

不管你喜不喜欢,事情就是这样。作为回应,我们需要做的是在设计枚举时,无论名称是合适的默认值,都将其值设为 0。如果没有合适的默认值,那么接受这样一个枚举作为参数的方法可能会检查它是否正确设置,例如

void ProcessColor(Color c) {
    if (c == 0)
        throw new ArgumentException("Color is not set", "c");
    //...
}
于 2012-05-24T17:56:38.507 回答
0

关键可能在于具有较少的正整数可能值。

为什么不那么积极

为了能够正确地处理带有位移操作的枚举。

我自然是在谈论默认值,可以由开发人员更改。

于 2012-05-24T17:28:42.520 回答
0

我不知道为什么,但是...

这是关于 C# 枚举的文档:http: //msdn.microsoft.com/en-us/library/sbbt4032.aspx

枚举器可以使用初始化器来覆盖默认值,如下例所示。

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

在此枚举中,元素的序列被强制从 1 而不是 0 开始。但是,建议包含一个值为 0 的常量。有关详细信息,请参阅枚举类型(C# 编程指南)

他们建议您始终包含一个与值 0 相对应的占位符枚举值,否则您可能会遇到问题。您可以将此枚举值命名为类似UndefinedDefault类似的名称。

正如我在对您的问题的评论中提到的那样,我的建议是根本不要为您的枚举使用值,除非您有充分的理由这样做。如果需要,请遵循MSDN Programming Guide for Enumeration Types

于 2012-05-24T17:55:46.390 回答
0

enumint(默认情况下)。对于我们的源代码,枚举是人类可读的整数,但是当你的程序被编译时,没有s enum,只有ints。int 的默认值为 0。

这段代码:

public enum test { One, Two, Three }

var x = test.One;
var y = 0;

在 IL 中变成这样:

IL_0001:  ldc.i4.0   
IL_0002:  stloc.0     
IL_0003:  ldc.i4.0    
IL_0004:  stloc.1 

那么,在某些情况下(如您所问),在其他情况下怎么可能int有默认值 1,但在其他情况下却没有呢?

于 2012-05-24T18:00:09.333 回答