什么是[标志]枚举属性在C#是什么意思? [英] What does the [Flags] Enum Attribute mean in C#?

查看:304
本文介绍了什么是[标志]枚举属性在C#是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我不时看到如下的枚举:

  [国旗]
公共枚举选项
{
    无= 0,
    选项​​1 = 1,
    选项​​2 = 2,
    选项​​3 = 4,
    选项​​4 = 8
}

我不明白究竟是什么 [国旗] -attribute一样。

任何人有一个很好的解释或例如,它们可以发布?


解决方案

中的标志属性每当枚举重presents标志位的集合,而不是一个单一的值应该被使用。这种集合使用位运算符通常操作,例如:

  myProperties.AllowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;

注意 [国旗] 本身并不改变这种所有 - 它是所有使一个很好的重新presentation由的ToString()方法:

 枚举西装{黑桃= 1,俱乐部= 2,钻石= 4,红心= 8}
[标志]枚举SuitsFlags {黑桃= 1,俱乐部= 2,钻石= 4,红心= 8}...变种STR1 =(Suits.Spades | Suits.Diamonds)的ToString();
           //5
VAR STR2 =(SuitsFlags.Spades | SuitsFlags.Diamonds)的ToString();
           //黑桃,钻石

同样重要的是要注意, [国旗] 自动进行的两个枚举值的权力。如果省略数值,枚举将无法正常工作如想象中位操作,因为默认情况下的值从0开始和增量。

错误声明:

  [国旗]
公共枚举MyColors
{
    黄色,
    绿色,
    红,
    蓝色
}

的值,如果这种方式声明,将黄色= 0,绿色= 1,红= 2,蓝色= 3,这将使其无法用作标志。

下面是一个正确声明的例子:

  [国旗]
公共枚举MyColors
{
    黄色= 1,
    绿色= 2,
    红色= 4,
    蓝色= 8
}

要检索您属性不同的值可以做到这一点。

  IF((myProperties.AllowedColors&安培; MyColor.Yellow)== MyColor.Yellow)
{
    //黄已设置...
}如果((myProperties.AllowedColors&安培; MyColor.Green)== MyColor.Green)
{
    //绿色已定...
}

,或在.NET 4及更高版本,

 如果(myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
    //黄已设置...
}

在幕后

这工作,因为你$ pviously使用的两种力量:你枚举p $。在幕后您枚举值看起来像这样(presented为字节,其中有8位可以是1或0)

 黄色:00000001
 绿色:00000010
 红色:00000100
 蓝色:00001000

同样,你设置你的财产后的 AllowedColors 的红,绿和蓝(其中值,其中通过管道或运算|)的 AllowedColors 的看起来像这样

  myProperties.AllowedColors:00001110

所以,当你retreive你的价值实际上是按位AND'ing的值

  myProperties.AllowedColors:00001110
             MyColor.Green:00000010
             -----------------------
                            00000010 //嘿,这是一样的MyColor.Green!

的无= 0值

和关于使用0您枚举,从MSDN报价:

  [国旗]
公共枚举MyColors
{
    无= 0,
    ....
}


  

使用无作为其值为零的标志枚举常量的名称。 您不能使用按位与运算列举恒定无来测试一个标志,因为结果始终为零。但是,您可以执行逻辑,不按位,数值和比较无枚举常以确定是否该数值任何位被置。


您可以获取更多有关标志属性,它的使用在 MSDN 在MSDN 设计标志

From time to time I see an enum like the following:

[Flags]
public enum Options 
{
    None    = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8
}

I don't understand what exactly the [Flags]-attribute does.

Anyone have a good explanation or example they could post?

解决方案

The flags attribute should be used whenever the enumerable represents a collection of flags, rather than a single value. Such collections are usually manipulated using bitwise operators, for example:

myProperties.AllowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;

Note that [Flags] by itself doesn't change this at all - all it does is enable a nice representation by the .ToString() method:

enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }

...

var str1 = (Suits.Spades | Suits.Diamonds).ToString();
           // "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
           // "Spades, Diamonds"

It is also important to note that [Flags] does not automatically make the enum values powers of two. If you omit the numeric values, the enum will not work as one might expect in bitwise operations, because by default the values start with 0 and increment.

Incorrect declaration:

[Flags]
public enum MyColors
{
    Yellow,
    Green,
    Red,
    Blue
}

The values, if declared this way, will be Yellow = 0, Green = 1, Red = 2, Blue = 3. This will render it useless for use as flags.

Here's an example of a correct declaration:

[Flags]
public enum MyColors
{
    Yellow = 1,
    Green = 2,
    Red = 4,
    Blue = 8
}

To retrieve the distinct values in you property one can do this

if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
    // Yellow has been set...
}

if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
    // Green has been set...
}    

or, in .NET 4 and later,

if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
    // Yellow has been set...
}

Under the covers

This works because you previously used powers of two in you enumeration. Under the covers your enumeration values looks like this (presented as bytes, which has 8 bits which can be 1's or 0's)

 Yellow: 00000001
 Green:  00000010
 Red:    00000100
 Blue:   00001000

Likewise, after you've set your property AllowedColors to Red, Green and Blue (which values where OR'ed by the pipe |), AllowedColors looks like this

myProperties.AllowedColors: 00001110

So when you retreive the value you are actually bitwise AND'ing the values

myProperties.AllowedColors: 00001110
             MyColor.Green: 00000010
             -----------------------
                            00000010 // Hey, this is the same as MyColor.Green!

The None = 0 value

And regarding use 0 in you enumeration, quoting from msdn:

[Flags]
public enum MyColors
{
    None = 0,
    ....
}

Use None as the name of the flag enumerated constant whose value is zero. You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set.

You can find more info about the flags attribute and its usage at msdn and designing flags at msdn

这篇关于什么是[标志]枚举属性在C#是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆