几天前我遇到了一只非常愚蠢的虫子。它是由我从第三方库获取的此枚举引起的:

[Flags]
public enum MyStatus
{
    OKResponse = 0,
    ResponseTooBig = 1,
    ErrorMessage = 2,
    NoResponse = 4,
    ...
}

我习惯这样检查标志:
if ((status & MyStatus.OKResponse) != 0) {...}

但它不适用于MyStatus.OKResponse,因为它是零。它根本不是一面旗帜,它是没有所有旗帜的。当然,当我发现这个bug时,我意识到OKResponse是唯一没有错误的状态,所以它实际上意味着“没有错误,没有标志”。不过,我真的觉得不太明显。
将0定义为标志枚举中的值之一是一个坏习惯吗?推荐的方法是什么?检查标志的最佳方法是什么,这也适用于“无标志”标志?

最佳答案

将0定义为标志枚举中的值之一是一个坏习惯吗?
不,相反,正如注释所说,通常使用0作为给定标志的值,如果没有为第一个给定值分配不同的值,则枚举将默认使用该值。正如其他人在评论中所说,使用Enum.None作为枚举的第一个值也是很常见的,这使您的意图对其他阅读代码的人更为清晰。
推荐的方法是什么?
没有一种方法可以做到,但我通常喜欢使用简洁的Enum.HasFlag方法:

void Main()
{
    var status = MyStatus.ResponseTooBig | MyStatus.NoResponse;
    if (status.Equals(MyStatus.OKResponse))
        Console.WriteLine("Status is OKResponse");
    else
        Console.WriteLine($"Has NoResponse?: {status.HasFlag(MyStatus.NoResponse)}");
}

10-04 12:24