C#中枚举Enum特性Flags和Enum.HasFlag(Enum)用法

2023-12-22 04:52

本文主要是介绍C#中枚举Enum特性Flags和Enum.HasFlag(Enum)用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

学习前需要了解位运算相关知识点。位运算介绍

Flags

标记可将枚举视为位域。

以下示例演示了FlagsAttribute特性的使用,并演示了对声明使用 [Flags] 后对 ToString 方法的影响。

   // Define an Enum without FlagsAttribute.enum SingleHue : short{None = 0,Black = 1,Red = 2,Green = 4,Blue = 8};// Define an Enum with FlagsAttribute.[Flags]enum MultiHue : short{None = 0,Black = 1,Red = 2,Green = 4,Blue = 8};static void Main( ){// Display all possible combinations of values.Console.WriteLine("All possible combinations of values without FlagsAttribute:");for(int val = 0; val <= 16; val++ )Console.WriteLine( "{0,3} - {1:G}", val, (SingleHue)val);// Display all combinations of values, and invalid values.Console.WriteLine("\nAll possible combinations of values with FlagsAttribute:");for( int val = 0; val <= 16; val++ )Console.WriteLine( "{0,3} - {1:G}", val, (MultiHue)val);}
// The example displays the following output:
//       All possible combinations of values without FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - 3
//         4 - Green
//         5 - 5
//         6 - 6
//         7 - 7
//         8 - Blue
//         9 - 9
//        10 - 10
//        11 - 11
//        12 - 12
//        13 - 13
//        14 - 14
//        15 - 15
//        16 - 16
//
//       All possible combinations of values with FlagsAttribute:
//         0 - None
//         1 - Black
//         2 - Red
//         3 - Black, Red
//         4 - Green
//         5 - Black, Green
//         6 - Red, Green
//         7 - Black, Red, Green
//         8 - Blue
//         9 - Black, Blue
//        10 - Red, Blue
//        11 - Black, Red, Blue
//        12 - Green, Blue
//        13 - Black, Green, Blue
//        14 - Red, Green, Blue
//        15 - Black, Red, Green, Blue
//        16 - 16

我们可以发现3在转SingleHue后还是3,但是在转MultiHue后变为了Black|Red,也就是说使用了位运算。

加了 [Flags] 特性后有三种写法,一种是使用<<符号,第二种是0x01, 还有一种是直接写0,1,2,4,8…,一般来说是2的n次方来表示。

	///<summary>/// 权限枚举///</summary>[Flags]public enum permission                     {                                  Unknown = 0; // 也可以写成0x00或0                            Create = 1<<0, // 0x01或1                   Read = 1<<1,  //0x02或2Update = 1<<2, //0x04或4Delete = 1<<3  //0x08或8}

对于位运算的应用

//1、给用户创建、读取,修改和删除的权限
var permission= permission.Create | permission.Read | permission.Update | permission.Delete;//2、去掉用户的修改和删除权限
permission= permission&~permission.Update;
permission= permission&~permission.Delete;//3、给用户加上修改的权限
permission = permission | permission.Update;//4、判断用户是否有创建的权限
var isCreate = (permission& permission.Create)!=0;
//或者
var isCreate = (permission & permission.Create)==permission.Create;

这时permission枚举的值将变成0+1+4=5,它的ToSting()将变成“permission.Create,permission.Read,permission.Update” 这里我们可以解释为什么第五个值Delete是8而不能成为5。也就是说它的值不应该是前几项值的复合值。一个比较简单的方法就是用2的n次方来依次位每一项赋值,例如:1,2,4,8,16,32,64…。

Enum.HasFlag(Enum)

确定当前实例中是否设置了一个或多个位域。
示例

[Flags] 
public enum DinnerItems {None = 0,Entree = 1,Appetizer = 2,Side = 4,Dessert = 8,Beverage = 16,BarBeverage = 32
}public class Example
{public static void Main(){DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |DinnerItems.Beverage | DinnerItems.Dessert;DinnerItems flagValue = DinnerItems.Entree | DinnerItems.Beverage;Console.WriteLine("{0} includes {1}: {2}",myOrder, flagValue, myOrder.HasFlag(flagValue));}
}
// The example displays the following output:
//    Entree, Appetizer, Dessert, Beverage includes Entree, Beverage: True

直白来说就是判断该值是否包含传入的枚举。

注意事项

需要注意如果传入HasFlag方法中的值为0那么会始终返回true,这种情况需要 Equals 方法或 CompareTo 来判断。
如果枚举值是从非0开始就不用考虑这个问题,如1、2、4、8…

这篇关于C#中枚举Enum特性Flags和Enum.HasFlag(Enum)用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/522668

相关文章

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

Mysql中isnull,ifnull,nullif的用法及语义详解

《Mysql中isnull,ifnull,nullif的用法及语义详解》MySQL中ISNULL判断表达式是否为NULL,IFNULL替换NULL值为指定值,NULLIF在表达式相等时返回NULL,用... 目录mysql中isnull,ifnull,nullif的用法1. ISNULL(expr) → 判

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编