枚举当然可以使代码更具可读性。还有一些事情需要注意(至少在 .net 中)
因为枚举的底层存储是 int,默认值将为零,因此您应该确保 0 是合理的默认值。 (例如,结构在创建时将所有字段设置为零,因此无法指定除 0 以外的默认值。如果您没有 0 值,您甚至无法在不强制转换为 int 的情况下测试枚举,这将是风格不好。)
如果您的枚举对您的代码是私有的(从不公开),那么您可以在此处停止阅读。
如果您的枚举以任何方式发布到外部代码和/或保存在程序之外,请考虑明确编号。编译器会自动从 0 开始对它们进行编号,但是如果您重新排列枚举而不给它们值,则最终可能会出现缺陷。
我可以合法写作
WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );
为了解决这个问题,任何使用您无法确定的枚举的代码(例如公共 API)都需要检查该枚举是否有效。您可以通过
if (!Enum.IsDefined(typeof(WriteMode), userValue))
throw new ArgumentException("userValue");
Enum.IsDefined 的唯一警告是它使用反射并且速度较慢。它还存在版本控制问题。如果您需要经常检查枚举值,您最好采用以下方法:
public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
switch( writeMode )
{
case WriteMode.Append:
case WriteMode.OverWrite:
break;
default:
Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
return false;
}
return true;
}
版本控制问题是旧代码可能只知道如何处理您拥有的 2 个枚举。如果添加第三个值,Enum.IsDefined 将为 true,但旧代码不一定能处理它。哎呀。
您可以使用[Flags] 枚举来做更多有趣的事情,并且验证代码略有不同。
我还要注意,为了可移植性,您应该在枚举上使用调用 ToString(),并在读回它们时使用 Enum.Parse()。ToString() 和 Enum.Parse() 也可以处理 [Flags] 枚举,所以没有理由不使用它们。请注意,这是另一个陷阱,因为现在您甚至无法更改枚举的名称而不会破坏代码。
所以,有时当您问自己时,您需要权衡以上所有因素我可以只用一个布尔值吗?