枚举应该具有未初始化的值。

时间:2008-12-06 02:07:23

标签: c# enums

如果枚举应该具有未初始化的值,我们就会进行辩论。例如。我们有

public enum TimeOfDayType
{
   Morning
   Afternoon
   Evening
}

public enum TimeOfDayType
{
   None
   Morning
   Afternoon
   Evening
}

我认为不应该没有,但是你必须在初始化时默认为某个有效值。但是其他人认为应该通过另一个枚举为None或NotSet来指示单一状态。

想法?

6 个答案:

答案 0 :(得分:13)

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

enum Color { Red, Blue }

让我们说你有一个功能:

void Draw(Color c);

该功能表示需要有效Color。但是,我们也可以使用此功能:

void Draw(Color? c);

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

嗯,它是None成员的另一种选择。

答案 1 :(得分:7)

我总是将我的一个枚举文字设置为零。此文字不能总是命名为“None”或“NotSet”。这取决于是否有一个文字作为默认行为。

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

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

答案 2 :(得分:4)

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

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

当然,以上所有都是概括性的。也许它无法应用于您的特定场景,因此如果您提供一些有关它的详细信息,我们可以更彻底地讨论该问题。

答案 3 :(得分:4)

在“默认”成员的绝对中,我认为有一个代表文字int 0的值是很有价值的。

无论如何,将使用字面值0创建给定的枚举。这里最直接的情况是作为结构的成员。 C#结构将始终具有一个空的默认构造函数,将所有字段初始化为其默认值。在枚举的情况下,这将是字面值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中,字段将简单地为“红色”。程序员无法在显式设置为“红色”或隐式默认值为“红色”之间进行检测。

另一种导致问题的情况是针对枚举值执行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&lt; Color2&gt;的默认构造函数,此代码将失败。并且没有办法压制这个构造函数。

这提出了一个更为重要的规则:对字面值0有一个明确的枚举值。

答案 4 :(得分:3)

只是添加到Franks的回答中,我唯一一次选择enum中的'None'项目是可以为空的,当枚举被用作标志时。 “无”项目的ID为0。

答案 5 :(得分:1)

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

这有点像是否应该使用可空类型。