需要澄清C#标志

时间:2010-04-16 02:31:43

标签: c# flags

我有这段代码:

[Flags]
public enum MyUriType {
    ForParse,
    ForDownload,
    Unknown
}

然后:

MyUriType uriType = MyUriType.ForDownload;

但是,我想知道为什么这会返回true:

if ((uriType & MyUriType.ForParse) == MyUriType.ForParse)

未在第二个代码组中设置时。请指教。

2 个答案:

答案 0 :(得分:8)

默认情况下,enum类型的第一个字段的序数值为0

因此,如果uriType不包含MyUriType.ForParse标记,那么uriType & MyUriType.ForParse实际上等于0,当您将其与true进行比较时,它会违反直觉评估为MyUriType.ForParse 0表示平等(也是({something} & 0) == 0 )。

如果将其分解为按位算术,那么您正在评估的表达式为:

true

...无论“某事”是什么,它总是会评估为Flags

通常,当您定义[Flags] public enum MyUriTypes { None = 0, ForParse = 1, ForDownload = 2, ForSomethingElse = 4, ForAnotherThing = 8 } 枚举时,您应该为每个字段指定值:

Flags

每个值应该是2的幂,这样它们就不会发生冲突(2的每个倍数都是二进制左移)。

将它命名为复数也是习惯用法,因此使用枚举的人知道它是false枚举,并且/可以/应该包含多个值。

如果您以这种方式定义枚举,那么如果uriType没有设置ForParse位,您的测试代码现在将评估为{{1}}。

答案 1 :(得分:0)

您应该以2的幂定义它,如:

[Flags]
public enum MyUriType {
None = 0
ForParse = 1,
ForDownload = 2,
Unknown = 4
}

请注意,当您希望设置选项组合时(例如ForParse + Unknown或ForDownload + Unknown),标记是合适的。如果一次只有一个选项适用,则可以使用常规枚举。