drz*_*aus 1 c# syntax enums flags
背景:按位枚举对于"更易读"的比较和检查非常有用:即OpenFile(write | append)
.
我已经看到了几种在C#中声明按位枚举的方法,但是最近其中一种常见模式似乎不再返回唯一值,我想知道我是在宣告它是错还是有些东西已经改变了.我在谈论"DWORD"(十六进制?)样式(如下所示),在VS2012 RC中枚举时,值为1,2,3,4 ...而不是预期的逐位加倍.
其他人可以重现这个吗?我发布了用于验证的代码以及控制台输出; ComparisonsDword
正如您可以通过"标记枚举,带有DWORD的显式值"的输出所看到的那样发生奇怪的行为.
没有标志,正常的枚举
/// <summary>
/// How to compare filter values; no underlying type declared, not flag
/// </summary>
public enum ComparisonsNotInt {
[Description("x")]
None
,
[Description("!=")]
NotEqual
,
[Description("=")]
Equal
,
[Description(">")]
GreaterThan
,
[Description("<")]
LessThan
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsNotFlag
Run Code Online (Sandbox Code Playgroud)
没有标志,底层类型= int
/// <summary>
/// How to compare filter values, not flag but underlying type declared
/// </summary>
public enum ComparisonsNotFlag : int {
[Description("x")]
None
,
[Description("!=")]
NotEqual
,
[Description("=")]
Equal
,
[Description(">")]
GreaterThan
,
[Description("<")]
LessThan
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsNotFlag
Run Code Online (Sandbox Code Playgroud)
标志,隐含价值
/// <summary>
/// How to compare filter values; values default to whatever .NET decides
/// </summary>
[Flags]
public enum ComparisonsImplicit : int {
[Description("x")]
None
,
[Description("!=")]
NotEqual
,
[Description("=")]
Equal
,
[Description(">")]
GreaterThan
,
[Description("<")]
LessThan
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsImplicit
Run Code Online (Sandbox Code Playgroud)
标志,显性值
/// <summary>
/// How to compare filter values; values explicitly defined with doubled numbers
/// </summary>
[Flags]
public enum ComparisonsExplicit : int {
[Description("x")]
None = 0
,
[Description("!=")]
NotEqual = 1
,
[Description("=")]
Equal = 2
,
[Description(">")]
GreaterThan = 4
,
[Description("<")]
LessThan = 8
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsExplicit
Run Code Online (Sandbox Code Playgroud)
标记,使用DWORD样式的显式值
注意:这是没有正确提供唯一值的内容,因此组合如GreaterThanOrEqual
失败.
/// <summary>
/// How to compare filter values; values explicitly defined with DWORD style
/// </summary>
[Flags]
public enum ComparisonsDword : int {
[Description("x")]
None = 0x0
,
[Description("!=")]
NotEqual = 0x1
,
[Description("=")]
Equal = 0x2
,
[Description(">")]
GreaterThan = 0x3
,
[Description("<")]
LessThan = 0x4
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsDword
Run Code Online (Sandbox Code Playgroud)
标记,使用DWORD样式的显式值 注意:也是不合适的值,只是检查基础类型是否影响问题.
/// <summary>
/// How to compare filter values; values explicitly defined with DWORD style
/// </summary>
[Flags]
public enum ComparisonsDwordNotInt {
[Description("x")]
None = 0x0
,
[Description("!=")]
NotEqual = 0x1
,
[Description("=")]
Equal = 0x2
,
[Description(">")]
GreaterThan = 0x3
,
[Description("<")]
LessThan = 0x4
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsDword
Run Code Online (Sandbox Code Playgroud)
标志,使用比特换档样式的显式值
/// <summary>
/// How to compare filter values; values explicitly set using shorthand of bitwise shifting
/// </summary>
[Flags]
public enum ComparisonsBitshift : int {
[Description("x")]
None = 0
,
[Description("!=")]
NotEqual = 1 << 0
,
[Description("=")]
Equal = 1 << 1
,
[Description(">")]
GreaterThan = 1 << 2
,
[Description("<")]
LessThan = 1 << 3
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsBitshift
Run Code Online (Sandbox Code Playgroud)
枚举输出:
Plain enum ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThan , Descr = >, Value = 3
Enum = GreaterThan , Descr = >, Value = 3 // bad: should be GTE
Enum = LessThan , Descr = <, Value = 4
Enum = LessThanOrEqual , Descr = <=, Value = 6
Plain enum, underlying int ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThan , Descr = >, Value = 3
Enum = GreaterThan , Descr = >, Value = 3 // bad: should be GTE
Enum = LessThan , Descr = <, Value = 4
Enum = LessThanOrEqual , Descr = <=, Value = 6
Flag enum, implicit values ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThanOrEqual, Descr = >=, Value = 3 // bad: should be GT
Enum = GreaterThanOrEqual, Descr = >=, Value = 3
Enum = LessThan , Descr = <, Value = 4
Enum = LessThanOrEqual , Descr = <=, Value = 6
Flag enum, explicit values ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThan , Descr = >, Value = 4
Enum = GreaterThanOrEqual, Descr = >=, Value = 6
Enum = LessThan , Descr = <, Value = 8
Enum = LessThanOrEqual , Descr = <=, Value = 10
Flag enum, explicit values with DWORD ---- // all of these are weirdly unexpected
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThanOrEqual, Descr = >=, Value = 3
Enum = GreaterThanOrEqual, Descr = >=, Value = 3
Enum = LessThan , Descr = <, Value = 4
Enum = LessThanOrEqual , Descr = <=, Value = 6
Flag enum, explicit values with DWORD, not underlying int ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThanOrEqual, Descr = >=, Value = 3
Enum = GreaterThanOrEqual, Descr = >=, Value = 3
Enum = LessThan , Descr = <, Value = 4
Enum = LessThanOrEqual , Descr = <=, Value = 6
Flag enum, explicit values with bitshifting ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThan , Descr = >, Value = 4
Enum = GreaterThanOrEqual, Descr = >=, Value = 6
Enum = LessThan , Descr = <, Value = 8
Enum = LessThanOrEqual , Descr = <=, Value = 10
Run Code Online (Sandbox Code Playgroud)
参考文献:
为了完整起见,我正在用@ kirk-woll的答案正确用法修改我原来的问题
修正了DWORD语法
/// <summary>
/// How to compare filter values; values explicitly defined with *correct* DWORD style
/// </summary>
[Flags]
public enum ComparisonsDwordCorrectlyDefined {
[Description("x")]
None = 0x0
,
[Description("!=")]
NotEqual = 0x1
,
[Description("=")]
Equal = 0x2
,
[Description(">")]
GreaterThan = 0x4
,
[Description("<")]
LessThan = 0x8
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="LessThan"/>
/// </summary>
[Description("<=")]
LessThanOrEqual = (Equal | LessThan)
,
/// <summary>
/// Combination of <see cref="Equal"/> and <see cref="GreaterThan"/>
/// </summary>
[Description(">=")]
GreaterThanOrEqual = (Equal | GreaterThan)
}//-- enum ComparisonsDwordCorrectlyDefined
Run Code Online (Sandbox Code Playgroud)
枚举输出
Flag enum, explicit values with correct DWORD ----
Enum = None , Descr = x, Value = 0
Enum = NotEqual , Descr = !=, Value = 1
Enum = Equal , Descr = =, Value = 2
Enum = GreaterThan , Descr = >, Value = 4
Enum = GreaterThanOrEqual, Descr = >=, Value = 6
Enum = LessThan , Descr = <, Value = 8
Enum = LessThanOrEqual , Descr = <=, Value = 10
Run Code Online (Sandbox Code Playgroud)
您的DWORD十六进制样式是错误的.你增加一个而不是加倍:
NotEqual = 0x1
Equal = 0x2
GreaterThan = 0x3
LessThan = 0x4
Run Code Online (Sandbox Code Playgroud)
应该:
NotEqual = 0x1
Equal = 0x2
GreaterThan = 0x4
LessThan = 0x8
Run Code Online (Sandbox Code Playgroud)
当然,在你开始上面之前,使用十六进制样式显然没有用8
:
LessThan = 0x8
GreaterThanOrEqual = 0x10
LessThanOrEqual = 0x20
Run Code Online (Sandbox Code Playgroud)
在这里它有点方便,因为加倍的进展导致简化的模式,而不是在脑中精神上加倍.