为什么我永远不会在标志枚举中使用0?我现在已多次阅读此内容并希望如此 知道原因:)
答案 0 :(得分:21)
因为Flag枚举是位集合或选项集。
0
值将是所有集合的一部分,或者不是。它只是行不通。
答案 1 :(得分:18)
为什么我永远不会在标志枚举中使用0?
这个问题是基于一个不正确的假设。您应该始终在标志枚举中使用零。它应始终设置为“无”。
除了表示“没有设置任何标志”之外,你不应该使用它。
为什么不呢?
因为如果零具有除“无”之外的含义,则会变得非常混乱。人们有理由期望((e & E.X) == E.X)
的意思是“X标志是否已设定?”但如果X为零,则此表达式将始终为真,即使逻辑该标志未“设置”。
答案 2 :(得分:3)
虽然零表示没有设置任何位,但将命名常量设为0通常非常有用。
当我设置标志字时,我定义了位的名称,以便它们都代表非默认值。也就是说,枚举值始终初始化为零,将“位”表示的所有选项“关闭”。
这为你的枚举提供了向前兼容性,这样任何创建新值的人都知道如果稍后在你的位域中添加更多标志,任何零位都将是“安全的”。
类似地,组合几个标志来创建一个新的常量名称非常有用,这使得代码更具可读性。
这种危险(以及引用规则的原因)只是你必须意识到单个位值(标志)和表示组或位组合的值之间的区别。
答案 3 :(得分:2)
标记枚举的用法如下:
Flag flags = Flag.First | Flag.Next | Flag.Last;
然后你应该像这样定义你的旗帜:
enum Flag {First = 1, Next = 2, Last = 4};
通过这种方式,您可以查看是否已使用过Flag,例如:
if (flags & Flag.First <> 0) Console.WriteLine("First is set");
if (flags & Flag.Next <> 0) Console.WriteLine("Next is set");
if (flags & Flag.Last <> 0) Console.WriteLine("Last is set");
这就是为什么你只能使用2的幂的值,例如1,2,4,8,16,32,64,128,...
如果flags为0,则认为它为空白。
我希望这会增加你对旗帜枚举的理解。
答案 4 :(得分:1)
因为通常使用标志如下:
var myFlagEnum = MyEnum.Foo | MyEnum.Bar | MyEnum.Bat;
// ... snip ...
if (myFlagEnum & MyEnum.Foo == MyEnum.Foo) { ... do something ... };
如果MyEnum.Foo为零,则上述操作无效(对于所有情况,它将返回true)。如果它是1,那么它会起作用。
答案 5 :(得分:1)
一个标志枚举假定它的每个值代表一个选项的存在,并且它在一个枚举位中编码。因此,如果存在特定选项(或为真),则枚举值中的equiveland位设置为(1),否则不设置(0)
因此每个枚举字段都是一个只设置了一个位的值。如果没有选项存在或为真,则组合的枚举值为零,这意味着没有设置任何位。因此,标志枚举中唯一的零字段是一个意味着没有设置,选择或选择任何选项的字段。
例如,假设我们有一个标记枚举,用于编码表格单元格中边框的存在
public enum BorderType
{
None = 0x00, // 00000000 in binary
Top = 0x01, // 00000001 in binary
Left = 0x02, // 00000010 in binary
Right = 0x04, // 00000100 in binary
Bottom = 0x08 // 00001000 in binary
}
如果要显示单元格中存在顶部和底部边框,则应使用值
Cell.Border = BorderType.Top | BorderType.Bottom; // 0x01 | 0x08 = 0x09 = 00001001 in binary
如果要显示单元格没有边框,则应使用值
Cell.Border = BorderType.None; // 0x00 = 00000000 in binary
所以你不应该在标志枚举中使用零作为选项的值,但是你应该总是使用零作为值,这意味着没有设置任何标志。
答案 6 :(得分:0)
我真的没有看到问题。
enum Where {Nowhere=0x00, Left=0x01, Right=0x02, Both=Left|Right};
Where thevalue = Where.Both;
bool result = (thevalue&Where.Nowhere)==Where.Nowhere;
当然结果是真的!你有什么期望?在这里,想一想。
bool result1 = (thevalue&Where.Left)==Where.Left;
bool result2 = (thevalue&Where.Right)==Where.Right;
bool result3 = (thevalue&Where.Both)==Where.Both;
这些全部是真的!为什么Nowhere
应该特别?关于0没什么特别的!