我理解Enums如何在C#中工作,并且我得到了Flags属性带来的内容。
我看到了这个问题,here。推荐第一种口味,但不提供任何理由/理由。
两者的定义方式是否存在差异,哪一个比另一个好?使用第一个synax代替第二个synax有什么好处?在定义Flags类型Enums时,我总是使用第二种风格......我一直都做错了吗?
[Serializable]
[Flags]
public enum SiteRoles
{
User = 1 << 0,
Admin = 1 << 1,
Helpdesk = 1 << 2
}
这与
不一样[Serializable]
[Flags]
public enum SiteRoles
{
User = 1,
Admin = 2,
Helpdesk = 4
}
答案 0 :(得分:6)
第一个的主要优点是您不需要为每个标志计算正确的值,因为编译器会为您执行此操作。除此之外,他们是一样的。
答案 1 :(得分:6)
考虑更复杂的样本:
[Flags]
public enum SiteRoles
{
User = 1 << 12,
Admin = 1 << 13,
Helpdesk = 1 << 15,
AdvancedUser = User | Helpdesk, //or (1<<12)|(1<<13)
}
[Flags]
public enum SiteRoles
{
User = 4096, //not so obvious!
Admin = 8192,
Helpdesk = 16384,
AdvancedUser = 12288, //!
}
[Flags]
public enum SiteRoles
{
User = 0x1000, //we can use hexademical digits
Admin = 0x2000,
Helpdesk = 0x4000,
AdvancedUser = 0x3000, //it much simpler calculate binary operator OR with hexademicals
}
此示例显示在这种情况下,第一个版本更具可读性。十进制文字不是表示标志常量的最佳方式。有关按位运算的更多信息(也可用于表示标志常量),请参阅http://en.wikipedia.org/wiki/Bitwise_operation
答案 2 :(得分:0)
AFAIK是一个可读性辩论。有人会说第一个更具可读性,因为你在'&lt;&lt;'的右侧有标志的实际索引。
答案 3 :(得分:0)
有另一种方法可以做到这一点相当优雅,所以我想我会分享我最近写的东西。它的好处是需要很少的数学,因此我认为它不易出错。它非常易读,恕我直言。
[Flags][Serializable]
public enum ScopeType : int
{
Unknown = 0,
Global = 1,
Namespace = Global << 1,
Class = Namespace << 1,
Struct = Class << 1,
Interface = Struct << 1,
Enum = Interface << 1,
Function = Enum << 1,
Property = Function << 1,
PropertyGetter = Property << 1,
PropertySetter = PropertyGetter << 1,
Using = PropertySetter << 1,
If = Using << 1,
ElseIf = If << 1,
Else = ElseIf << 1,
Switch = Else << 1,
Case = Switch << 1,
For = Case << 1,
While = For << 1,
DoWhile = While << 1,
Lambda = DoWhile << 1,
Try = Lambda << 1,
Catch = Try << 1,
Finally = Catch << 1,
Initializer = Finally << 1,
Checked = Initializer << 1,
Unchecked = Checked << 1,
Unsafe = Unchecked << 1,
Lock = Unsafe << 1,
Fixed = Lock << 1,
// I can also group flags together using bitwise-OR.
PropertyAccessor = PropertyGetter | PropertySetter,
TypeDefinition = Class | Struct | Interface | Enum,
TryCatchFinally = Try | Catch | Finally,
Conditional = If | ElseIf | Else,
Branch = Conditional | Case | TryCatchFinally,
Loop = For | While | DoWhile
}
注意:由于枚举继承自System.Int32
,因此我只能定义32个标志。如果您需要更多,则必须使用更大的整数(System.Int64
),创建多个枚举并将它们链接在一起,或者只创建一个包含一堆布尔值的类。