9

我们正在争论枚举是否应该具有未初始化的值。例如。我们有

public enum TimeOfDayType
{
   Morning
   Afternoon
   Evening
}

或者

public enum TimeOfDayType
{
   None
   Morning
   Afternoon
   Evening
}

我认为不应该有任何内容,但是您必须在初始化时默认为某个有效值。但其他人认为应该通过另一个为 None 或 NotSet 的枚举来表明统一状态。

想法?

4

6 回答 6

13

说到可空类型——我认为它们可以用来解决强制/不强制初始化枚举的问题。说我们有

enum Color { Red, Blue }

假设你有一个函数:

void Draw(Color c);

该函数说它需要一个有效的Color. 但是,我们也可以有这个功能:

void Draw(Color? c);

这表示该函数可以处理不传递颜色(null将传递以表示“不关心”)。

嗯,这是成员的一种选择None

于 2008-12-06T02:33:36.247 回答
7

我总是将我的枚举文字之一设置为零。此文字不得总是命名为“None”或“NotSet”。这取决于是否有一个文字可以很好地作为默认值。

我将 1 设置为 0,因为枚举(可空枚举除外)总是由内存中的 CLR 初始化为零。如果您没有定义其中一种文字,则此内存包含非法值。此外,当您使用枚举作为标志时。默认值不能用于按位比较。结果将始终为零。

当您启用 FxCop 时,它会检查您是否已将文字定义为默认值。当他们有规则时,这似乎是一种“好习惯”。

于 2008-12-06T08:32:39.593 回答
5

在之前的一些答案中,提出了一个可以为空的枚举作为解决方案。但是可空枚举的缺点是它使客户端每次使用枚举时都检查空值。相反,如果您有一个默认值“None”,您可以选择使用开关来获取有意义的值,而忽略“None”,而不必担心枚举变量可能为空。

无论如何,我认为只有当枚举用作某个类的默认构造函数中的参数时,才有默认值“无”或使枚举为空才有意义。你必须问自己——那个类的对象不应该有一些有意义的默认值吗?将您的示例与 TimeOfDayType 枚举一起使用 - 如果您使用 TimeOfDayType.None 初始化对象,则在将值更改为 Morning、Afternoon 或 Evening 之前无论如何都不能使用它。所以你不能说默认是 Morning 而不是 None 吗?或者——更好的是——在你已经知道它们需要哪个枚举值之后,你不能创建你的对象吗?我认为,如果在早期设计阶段正确解决了该问题,则根本不需要为枚举设置特殊的默认值。

当然,以上都是概括。也许它不能应用于你的特定场景,所以如果你提供一些关于它的细节,我们可以更彻底地讨论这个问题。

于 2008-12-06T04:00:46.490 回答
5

在没有“默认”成员的情况下,我认为拥有一个表示文字 int 0 的值是有价值的。

无论如何,将使用字面值 0 创建给定的枚举。这里最直接的情况是作为结构的成员。AC# struct 将始终有一个空的默认构造函数,它将所有字段初始化为其默认值。在枚举的情况下,这将是文字值 0。问题是如何处理它。

对我来说,这是一个风格问题:如果枚举没有显式初始化为一个值,应该给它一个任意的有效值还是一个表示缺乏显式初始化的特定值?

enum Color { Unknown, Red, Blue }
enum Color2 { Red,Blue }
struct Example<T> {
  Color color;
}

static void SomeMethod() {
  var v1 = new Example<Color>();
  var v2 = new Example<Color2>();
}

在 v1 的情况下,如果检查了颜色字段,它将被明确标记为未初始化的字段。在 v2 中,该字段将简单地为“红色”。程序员无法检测到显式设置为“Red”或隐式默认值设置为“Red”。

导致问题的另一种情况是针对枚举值执行 switch 语句。让我们稍微改变 Color2 的定义。

enum Color2 { Red = 1, Blue = 2 }
static void SomeOtherMethod(p1 as Example<Color2>) {
  switch ( p1.color ) {
   case Color.Red: {} 
   case Color.Blue: {}
   default: {throw new Exception("What happened?"); }
  }
}

开关处理枚举中的每个显式值。然而,对于 Example<Color2> 的默认构造函数,此代码将失败,并且无法抑制此构造函数。

这带来了一个稍微重要的规则:为字面值 0 有一个显式的枚举值。

于 2008-12-06T04:01:20.250 回答
3

只是添加到 Franks 的答案,我会在枚举中选择“无”项而不是可为空的唯一一次是当枚举被用作标志时。“无”项目的 id 为 0。

于 2008-12-06T02:54:26.763 回答
1

取决于类型的使用方式。对于该类型的用户来说,没有“未定义”值通常更容易,因为您不必对一个值进行特殊处理。但是如果你需要一个(因为值有时需要处于一个不是任何枚举值的状态),那么你需要一个。您通常不会通过使用两个枚举而不是一个枚举来保存任何特殊情况代码。

这有点像问你是否应该使用可为空的类型。

于 2008-12-06T02:14:17.860 回答