此讨论是关于默认值的名称: C#: Should the default value of an enum be None or Unknown?
然而,我最近与之交谈过的大量人认为默认值是有害的,不必要的,并可能导致不良做法。
作为一个例子考虑以下内容:
enum eJobStates
{
JOB_STATE_INITIALISING,
JOB_STATE_PROCESSING,
JOB_STATE_DONE
};
对于一个JOB_STATE_UNKNOWN这样的工作是没有意义的,但你可以想象任何可能用于监控所述工作的结构都可以使用这样的值。
在定义枚举时是否有关于创建默认值的最佳实践/经验法则?是否应尽可能不惜一切代价避免它们?
答案 0 :(得分:2)
无效的默认值基本上是您设计中的变体。该对象在创建时无效。当它合理时,你应该避免这种情况。绝不应该“不惜一切代价”避免它。
有些问题需要您从变体状态开始。在这种情况下,您 在心理上推断该无效值。如果你避免命名它,你就会积极地使你的代码表现力降低。考虑一下你和那些必须在以后维护代码的人之间的沟通。
顺风处理令人讨厌。你从一个变体状态开始,但是当它相关时,你希望它不再是变体。我更喜欢的策略是允许用户忽略变体状态,并在我犯错误时抛出。
namespace FooType {
enum EnumValue {
INVALID = 0
,valid
};
}
struct Foo {
Foo() : val(FooType::INVALID) {}
FooType::EnumValue get() const {
if (val == FooType::INVALID)
throw std::logic_error("variant Foo state");
return val;
}
FooType::EnumValue val;
};
这使您的用户不必理由您的差异,这值得为之奋斗。
如果你无法逃避,我通常更倾向于降级到安全和不安全的界面。
struct Foo {
Foo() : val(FooType::INVALID) {}
bool get(FooType::EnumValue& val_) const {
if (val == FooType::INVALID)
return false;
val_ = val;
return true;
}
FooType::EnumValue get() const {
FooType::EnumValue val_;
if (!get(val_))
throw std::logic_error("variant Foo state");
return val_;
}
FooType::EnumValue get_or_default(FooType::EnumValue def) const {
FooType::EnumValue val_;
if (!get(val_))
return def;
return val_;
}
FooType::EnumValue val;
};
这些类型的接口适用于像数据库这样的东西,其中可能需要空值。