使用属性定义C#枚举的多种方法?

我理解Enums如何在C#中工作,我得到了Flags属性带给表的内容。

我在这里看到了这个问题。 其中推荐了第一种口味,但没有提供任何理由/理由。

两者的定义方式是否存在差异,哪一个比另一个好? 使用第一个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 } 

第一个的主要优点是您不需要为每个标志计算正确的值,因为编译器会为您执行此操作。 除此之外他们是一样的。

考虑更复杂的样本:

 [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

AFAIK是一个可读性辩论。 有人会说第一个更具可读性,因为你在’<<'右侧有标志的实际索引。

有另一种方法可以做到这一点,相当优雅,所以我想我会分享我最近写的东西。 它的好处是需要很少的数学,因此我认为它不易出错。 它很可读,恕我直言。

 [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 } 

注意:由于枚举inheritance自System.Int32 ,因此我只能定义32个标志。 如果需要更多,则必须使用更大的整数( System.Int64 ),创建多个枚举并将它们链接在一起,或者只创建一个带有一堆布尔值的类。