我有以下代码:
namespace ConsoleApplication1
{
internal class Program
{
[FlagsAttribute]
private enum RenderType
{
DataUri = 0,
GZip = 1,
ContentPage = 2,
ViewPage = 4,
HomePage = 8
}
private static void Main()
{
// 4.
// Set a new enum in three statements.
RenderType type2 = RenderType.ViewPage;
// 5.
// See if the enum contains this flag.
if ((type2 & RenderType.ViewPage) == RenderType.ViewPage)
{
Console.WriteLine("ViewPage");
}
if ((type2 & RenderType.DataUri) == RenderType.DataUri)
{
Console.WriteLine("DataUri");
}
if ((type2 & RenderType.GZip) == RenderType.GZip)
{
Console.WriteLine("GZip");
}
}
}
}
每当我运行此代码时,它都会给出一个输出:
的ViewPage DataUri
我想要输出只是ViewPage,因为我将值赋给我的枚举ViewPage。
有人可以帮我吗?为什么是这样?我的Enum声明或代码有什么问题吗?
答案 0 :(得分:4)
您已声明DataUri = 0
所以
(type2 & RenderType.DataUri) == RenderType.DataUri
将始终评估为true
。
在1开始有效的枚举值。
答案 1 :(得分:1)
任何以零为单位的数字都为零。用一个开始枚举,用两个幂增加。此外,更好地了解binary numbers和bitwise operators将有助于
答案 2 :(得分:1)
DataUri为0:所以x & DataUri
始终为零!
试试这个:
if(type2 != RenderType.DataUri) {
if ((type2 & RenderType.ViewPage) == RenderType.ViewPage)
{
Console.WriteLine("ViewPage");
}
if ((type2 & RenderType.GZip) == RenderType.GZip)
{
Console.WriteLine("GZip");
}
}
使用Bitmasks时,值0通常表示NONE-Flag。所以你应该从1到2 ^ n开始计数,这是一个更好的做法恕我直言:
[FlagsAttribute]
private enum RenderType
{
None = 0,
DataUri = 1,
GZip = 2,
ContentPage = 4,
ViewPage = 8,
HomePage = 16
}
答案 3 :(得分:0)
因为x & 0
总是等于零。
答案 4 :(得分:0)
不要将0(零)指定为[Flags]枚举的可能值。请记住,[Flags]枚举是一个位字段,值为零并不真正映射到任何字段,因此它将始终返回true。
来自Krzysztof Cwalina的Framework Design Guidelines:
Avoid using flag enum values normal members that are negative or zero.
负值会在按位运算中产生意外/混乱的结果。枚举值为零会产生问题和操作等:
答案 5 :(得分:0)
原因是RenderType.DataUri
的值为0
。
您的代码所做的是通过在type2
和它正在测试的枚举成员之间执行按位and
操作来检查type2
枚举变量的按位配置。
在您的示例中,type2
的值为4,二进制为0100
(最多为枚举所需的4位)。当您测试RenderType.GZip
(0001
)时,会执行以下计算:
0100 & 0001 = 0000
自0000 != 0001
起,RenderType.GZip
位未在type2
中设置。但是,0100 & 0000
始终为0000
,因此在检查RenderType.DataUri
时您始终会成真。
本质上,Flags
枚举对每个成员使用不同的位,但由于0
不表示整数中的位,因此它不会按预期运行。
答案 6 :(得分:0)
正如其他人所说,由于二元算法的工作原理,你应该在1开始使用Flags枚举。我只想补充一点,你可能想要使用HasFlag方法(我相信.NET 4.0中的新方法)来检查标志:
if(type2.HasFlag(RenderType.ViewPage))
{
...
}
http://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx