FlagsAttribute Enum在C#中的行为是什么?
我有以下代码:FlagsAttribute Enum在C#中的行为是什么?,c#,.net,enums,C#,.net,Enums,我有以下代码: namespace ConsoleApplication1 { internal class Program { [FlagsAttribute] private enum RenderType { DataUri = 0, GZip = 1, ContentPage = 2, ViewPage = 4,
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");
}
}
}
}
每当我运行此代码时,它都会为我提供以下输出:
查看页面
数据URI
当我给我的enum ViewPage赋值时,我只需要ViewPage的输出
有人能帮我吗?为什么会这样?我的枚举声明或代码有什么问题吗 任何按位与零AND的数字都是零。以1开始枚举,并增加2的幂。此外,更好地理解and将有助于任何按位and加零的数字都是零。以1开始枚举,并增加2的幂。此外,更好地理解和将有助于因为
x&0
始终等于零。因为x&0
始终等于零。您已经声明DataUri=0
所以
(type2 & RenderType.DataUri) == RenderType.DataUri
将始终计算为true
将有效枚举值从1开始。您已声明
DataUri=0
so
(type2 & RenderType.DataUri) == RenderType.DataUri
将始终计算为true
将有效枚举值从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");
}
}
使用位掩码时,值0通常表示无标志。所以你应该开始从1数到2^n,这是一个更好的练习IMHO:
[FlagsAttribute]
private enum RenderType
{
None = 0,
DataUri = 1,
GZip = 2,
ContentPage = 4,
ViewPage = 8,
HomePage = 16
}
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");
}
}
使用位掩码时,值0通常表示无标志。所以你应该开始从1数到2^n,这是一个更好的练习IMHO:
[FlagsAttribute]
private enum RenderType
{
None = 0,
DataUri = 1,
GZip = 2,
ContentPage = 4,
ViewPage = 8,
HomePage = 16
}
不要将0(零)指定为[Flags]枚举的可能值。请记住,[Flags]枚举是一个位字段,零的值实际上不会映射到任何字段,因此它将始终返回true
来自Krzysztof Cwalina的报告:
负值会在按位操作中产生意外/混乱的结果。枚举值为零会导致和操作等问题:
不要将0(零)指定为[Flags]枚举的可能值。请记住,[Flags]枚举是一个位字段,零的值实际上不会映射到任何字段,因此它将始终返回true
来自Krzysztof Cwalina的报告:
负值会在按位操作中产生意外/混乱的结果。枚举值为零会导致和操作等问题:
原因是
RenderType.DataUri
的值为0
代码所做的是通过在type2
和它测试的枚举成员之间执行按位和操作来检查type2
枚举变量的按位配置
在您的示例中,type2
的值为4,二进制形式为0100
(最多为枚举所需的4位)。测试RenderType.GZip
(0001
)时,它会执行以下计算:
0100 & 0001 = 0000
自0000!=0001
,未在type2
中设置RenderType.GZip
位。但是,0100&0000
始终是0000
,因此在检查RenderType.DataUri
时总是会得到true
本质上,标志
枚举为其每个成员使用不同的位,但由于0
不表示整数中的位,因此它不会按预期的方式工作。原因是RenderType.DataUri
的值为0
代码所做的是通过在type2
和它测试的枚举成员之间执行按位和操作来检查type2
枚举变量的按位配置
在您的示例中,type2
的值为4,二进制形式为0100
(最多为枚举所需的4位)。测试RenderType.GZip
(0001
)时,它会执行以下计算:
0100 & 0001 = 0000
自0000!=0001
,未在type2
中设置RenderType.GZip
位。但是,0100&0000
始终是0000
,因此在检查RenderType.DataUri
时总是会得到true
本质上,Flags
enum对其每个成员使用不同的位,但由于0
不表示整数中的位,因此它的行为将不符合预期。正如其他人所说,由于二进制算术的工作方式,您应该将Flags enum从1开始。我只想补充一点,您可能希望使用HasFlag方法(我相信在.NET 4.0中是新的)来检查标志:
if(type2.HasFlag(RenderType.ViewPage))
{
...
}
正如其他人所说,由于二进制算术的工作方式,您应该将标志枚举从1开始。我只想补充一点,您可能希望使用HasFlag方法(我相信在.NET 4.0中是新的)来检查标志:
if(type2.HasFlag(RenderType.ViewPage))
{
...
}
小说明:实际上,C#中没有[Flags]
的特定行为-它的行为与任何枚举
(或整数)完全相同。BCL有一些[Flags]
处理(例如,序列化),一些IDE工具也是如此。但是语言:对[Flags]
一点也不关心。小说明:实际上,在C#中没有[Flags]
的特定行为-它的行为与任何枚举
(或整数)完全相同。BCL有一些[Flags]
处理(例如,序列化),一些IDE工具也是如此。但是语言:一点也不关心[Flags]
。