如果枚举应该具有未初始化的值,我们就会进行辩论.例如.我们有
public enum TimeOfDayType { Morning Afternoon Evening }
要么
public enum TimeOfDayType { None Morning Afternoon Evening }
我认为不应该没有,但是你必须在初始化时默认为某个有效值.但是其他人认为应该通过另一个枚举为None或NotSet来表明单一状态.
想法?
说到可空类型 - 我认为它们可以用来解决强制/不强制枚举初始化的问题.说我们有
enum Color { Red, Blue }
让我们说你有一个功能:
void Draw(Color c);
该函数表示它需要有效Color
.但是,我们也可以有这个功能:
void Draw(Color? c);
这表示该函数可以处理不传递颜色(null
将传递以表示"不关心").
嗯,这是None
会员的另一种选择.
我总是将我的一个枚举文字设置为零.此文字不能总是命名为"None"或"NotSet".这取决于是否有一个文字作为默认行为.
我将1设置为零,因为枚举(除了可以为空的枚举)总是由内存中的CLR初始化为零.如果您没有定义其中一个文字,则此内存包含非法值.当你使用枚举作为标志时.默认值不能用于执行按位compairisons.结果将始终为零.
启用FxCop时,它会检查您是否已将文字定义为默认值.当他们有规则时,似乎是一个"好习惯".
在以前的某些答案中,提出了可为空的枚举作为解决方案。但是可为空的枚举的缺点是,使客户端每次使用枚举时都会检查空值。相反,如果您的默认值为“ None”,则可以选择对有意义的值使用开关,而忽略“ None”,而不必担心enum变量可以为null。
无论如何,我认为只有将枚举用作某个类的默认构造函数中的参数时,将默认值设置为“ None”或使枚举可为空才有意义。您必须问自己-该类的对象是否应该具有有意义的默认值?将您的示例与TimeOfDayType枚举一起使用-如果您使用TimeOfDayType.None初始化对象,则在将值更改为Morning,Afternoon或Evening之前仍然无法使用它。因此,您不能说默认值是Morning而不是None吗?或者-更好的是-在知道对象需要哪个枚举值之后不能创建对象吗?我认为,如果在设计的早期阶段正确解决了该问题,则根本不需要为枚举指定特殊的默认值。
当然,以上所有都是概括。也许它不能应用于您的特定情况,因此,如果您提供有关它的一些详细信息,我们可以更全面地讨论该问题。
在“默认”成员缺席的情况下,我认为具有一个表示原汁原味的整数0的值很有价值。
无论如何,将使用文本值0创建给定的枚举。这里最直接的情况是作为struct的成员。AC#结构将始终具有一个空的默认构造函数,该构造函数将所有字段初始化为它们的默认值。对于枚举,它将是字面值0。问题是如何处理它。
对我来说,这是一个样式问题:如果没有将枚举显式初始化为一个值,是否应该给它一个任意的有效值或一个特定的值,以指示缺少显式初始化?
enum Color { Unknown, Red, Blue } enum Color2 { Red,Blue } struct Example{ Color color; } static void SomeMethod() { var v1 = new Example (); var v2 = new Example (); }
对于v1,如果检查了颜色字段,则将其显式标记为未初始化的字段。在v2中,该字段将简单为“红色”。程序员无法检测到显式设置为“ Red”或隐式默认值为“ Red”。
引起问题的另一种情况是针对枚举值执行switch语句。让我们稍微更改一下Color2的定义。
enum Color2 { Red = 1, Blue = 2 } static void SomeOtherMethod(p1 as Example) { switch ( p1.color ) { case Color.Red: {} case Color.Blue: {} default: {throw new Exception("What happened?"); } } }
开关处理枚举中的每个显式值。但是,对于Example
这引出了一条更为重要的规则:为文字值0提供一个明确的枚举值。