C# 中的 [Flags] 枚举属性是什么意思?

What does the [Flags] Enum Attribute mean in C#?(C# 中的 [Flags] 枚举属性是什么意思?)
本文介绍了C# 中的 [Flags] 枚举属性是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我会看到类似以下的枚举:

[标志]公共枚举选项{无 = 0,选项1 = 1,选项2 = 2,选项3 = 4,选项 4 = 8}

我不明白 [Flags] 属性到底是做什么的.

任何人都可以发布一个很好的解释或示例吗?

解决方案

当可枚举表示可能值的集合而不是单个值时,应使用 [Flags] 属性.此类集合通常与位运算符一起使用,例如:

var allowedColors = MyColor.Red |我的颜色.绿色 |我的颜色.蓝色;

请注意,[Flags] 属性 自己启用此功能 - 它所做的只是允许 .ToString() 方法:

enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }[标志] 枚举 SuitsFlags { 黑桃 = 1,梅花 = 2,方块 = 4,红心 = 8 }...var str1 = (Suits.Spades | Suits.Diamonds).ToString();//5"var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();//黑桃,方块"

还需要注意的是,[Flags] 不会自动将枚举值设为 2 的幂.如果省略数值,枚举将不会像人们期望的那样在按位运算中工作,因为默认情况下,值从 0 开始并递增.

不正确的声明:

[标志]公共枚举 MyColors{黄色,//0绿色,//1红色,//2蓝色//3}

如果以这种方式声明,值将是 Yellow = 0、Green = 1、Red = 2、Blue = 3.这将使它无法用作标志.

以下是正确声明的示例:

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

要检索属性中的不同值,可以这样做:

if (myProperties.AllowedColors.HasFlag(MyColor.Yellow)){//黄色是允许的...}

或在 .NET 4 之前:

if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow){//黄色是允许的...}if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green){//允许绿色...}

幕后

之所以有效,是因为您在枚举中使用了 2 的幂.在幕后,您的枚举值在二进制 1 和 0 中如下所示:

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

同样,在您使用二进制按位 OR | 运算符将属性 AllowedColors 设置为 Red、Green 和 Blue 后,AllowedColors 看起来像这样:

myProperties.AllowedColors: 00001110

因此,当您检索值时,您实际上是在对这些值执行按位与 &:

myProperties.AllowedColors: 00001110我的颜色.绿色:00000010----------------------00000010//嘿,这和 MyColor.Green 一样!

None = 0 值

关于 0 在您的枚举中的使用,引用自 MSDN:

[标志]公共枚举 MyColors{无 = 0,……}

<块引用>

使用 None 作为其值为 0 的标志枚举常量的名称.您不能在按位与运算中使用 None 枚举常量来测试标志,因为结果始终为零.但是,您可以在数值和None 枚举常量,用于确定数值中是否设置了任何位.

您可以在 msdn 找到有关 flags 属性及其用法的更多信息 和 在 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 possible values, rather than a single value. Such collections are often used with bitwise operators, for example:

var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;

Note that the [Flags] attribute doesn't enable this by itself - all it does is allow 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,  // 0
    Green,   // 1
    Red,     // 2
    Blue     // 3
}

The values, if declared this way, will be Yellow = 0, Green = 1, Red = 2, Blue = 3. This will render it useless 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 your property, one can do this:

if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
    // Yellow is allowed...
}

or prior to .NET 4:

if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
    // Yellow is allowed...
}

if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
    // Green is allowed...
}    

Under the covers

This works because you used powers of two in your enumeration. Under the covers, your enumeration values look like this in binary ones and zeros:

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

Similarly, after you've set your property AllowedColors to Red, Green and Blue using the binary bitwise OR | operator, AllowedColors looks like this:

myProperties.AllowedColors: 00001110

So when you retrieve the value you are actually performing bitwise AND & on the values:

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

The None = 0 value

And regarding the use of 0 in your 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# 中的 [Flags] 枚举属性是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)