【发布时间】:2016-03-07 09:48:35
【问题描述】:
几天前我遇到了一个非常愚蠢的错误。这是由我从第三方库获得的这个枚举引起的:
[Flags]
public enum MyStatus
{
OKResponse = 0,
ResponseTooBig = 1,
ErrorMessage = 2,
NoResponse = 4,
...
}
我习惯用这种方式检查标志:
if ((status & MyStatus.OKResponse) != 0) {...}
但它不适用于MyStatus.OKResponse,因为它为零。它根本不是一面旗帜,它是所有旗帜的缺失。当然,当我发现 bug 时,我意识到 OKResponse 是唯一的非错误状态,所以它的真正意思是“没有错误,没有标志”。但是,我真的不觉得很明显。
将 0 定义为 flags 枚举中的值之一是一个坏习惯吗?推荐的方法是什么?检查标志的最佳方法是什么,也可以与“无标志”标志一起使用?
【问题讨论】:
-
这不仅不是一个坏习惯,而且恰恰相反——不定义零值是不好的。这是因为枚举的默认值为 0。惯例是调用它
None。此外,当使用[Flags]时,约定是枚举名称的复数形式。看起来你的枚举应该被称为Errors。 -
为此使用标志枚举似乎是错误的。您是否有一个由多个位表示的状态?
-
@Steve 是的,我不得不把这个例子匿名化一点......第一个是 OKResponse,其余的是一些错误标志,不止一个可能。使用标志是可以的,真的。
-
请注意,如果您将
None = 0添加到枚举中,您的检查将变为if (status != Errors.None),这非常易读。 (而且我认为您需要添加一个None成员并将枚举重命名为遵循 the enum naming convention。) -
@Jodrell 是的,当然。但我必须知道
MyStatus.OKResponse是一个特殊的值......我真的应该检查我得到的所有库中的所有枚举吗?
标签: c# enums flags anti-patterns