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

相关文章

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

SQL Server中的PIVOT与UNPIVOT用法具体示例详解

《SQLServer中的PIVOT与UNPIVOT用法具体示例详解》这篇文章主要给大家介绍了关于SQLServer中的PIVOT与UNPIVOT用法的具体示例,SQLServer中PIVOT和U... 目录引言一、PIVOT:将行转换为列核心作用语法结构实战示例二、UNPIVOT:将列编程转换为行核心作用语

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

Java中 instanceof 的用法详细介绍

《Java中instanceof的用法详细介绍》在Java中,instanceof是一个二元运算符(类型比较操作符),用于检查一个对象是否是某个特定类、接口的实例,或者是否是其子类的实例,这篇文章... 目录引言基本语法基本作用1. 检查对象是否是指定类的实例2. 检查对象是否是子类的实例3. 检查对象是否

Java中的内部类和常用类用法解读

《Java中的内部类和常用类用法解读》:本文主要介绍Java中的内部类和常用类用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录内部类和常用类内部类成员内部类静态内部类局部内部类匿名内部类常用类Object类包装类String类StringBuffer和Stri

C#实现查找并删除PDF中的空白页面

《C#实现查找并删除PDF中的空白页面》PDF文件中的空白页并不少见,因为它们有可能是作者有意留下的,也有可能是在处理文档时不小心添加的,下面我们来看看如何使用Spire.PDFfor.NET通过C#... 目录安装 Spire.PDF for .NETC# 查找并删除 PDF 文档中的空白页C# 添加与删

通过C#获取Excel单元格的数据类型的方法详解

《通过C#获取Excel单元格的数据类型的方法详解》在处理Excel文件时,了解单元格的数据类型有助于我们正确地解析和处理数据,本文将详细介绍如何使用FreeSpire.XLS来获取Excel单元格的... 目录引言环境配置6种常见数据类型C# 读取单元格数据类型引言在处理 Excel 文件时,了解单元格

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async