c# 枚举和位标志

今天我们来讲一讲  枚举类型和 位标志

一、Enum(枚举)

   值类型,继承于system.Enum

c# 枚举和位标志


c# 枚举和位标志


c# 枚举和位标志


通过几种语言的对比,我们可以知道,如果不给枚举类型赋值,默认会从第一个赋0值,依次递增, 

在编译枚举类型时,会把每个符号转换成类型的一个常量字段很一个int32的公共实例字段,不够后者不能通过代码调用。

因为枚举的符号是一个常量字段,如果在不同的程序集引用,可能会出现一些版本问题,【在常量中有说明   传送门


c# 枚举和位标志每个枚举都有一个基础类型, 包含 byte,sbyte,short,ushort,uint,long ,ulong, 和int (最常用,C#默认的类型)

 枚举中的符号属于值类型,我们就可以通过反射获取到其值跟符号了 ,但 枚举提供了几种方法:

1.Tostring()

c# 枚举和位标志

我们通过Tostring()可以获取符号字符串,符号的值,已经 十进制,十六进制, 

枚举还提供了一个方法是Format(Type enumType,Object value,String format)

这个唯一的一个优势 是可以允许传递数值类型。

2.GetValues()

c# 枚举和位标志

  通过GetValues()方法 可以获取到枚举的所有符号集合和所有的值,它返回的是一个Array

 Enum 还提供了GetNames(),返回一个string[] ,它只能获取到符号字符串,

如果要取值的话,要通过  GetName(Type enumType,Object Values); 方法,可以通过字符取到枚举类型的值。

3.Parse 和TryParse 

   经常看到一个类型提供的转换方法的时候,有两个方法很相似,比如是 XXX 和TryXXX  从字面意思我可以知道,一个是异常处理,另外一个是直接抛出异常,还有一个共同点 就是 都要Out 一个值。

 Enum.Parse(Type enumType, string value, bool ignoreCase), 这个是把符号子串 转换成一个枚举类型,第三个参数是是否识别大小写, 还有就是如果当前转换的 数值不存在,则抛出异常。

 TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) where TEnum : struct;

这个方法是经过处理异常,如果转换成功返回true,否则返回false, 而且加了一个值类型约束,同样也有区分符号大小写的参数

4.IsDefined()

这个方法是检查枚举类型是否存在的

 bool IsDefined(Type enumType, object value);

value 参数可以是 符号 ,也可以是数值。

本人不推荐使用该方法,虽然很方便,但是在使用这个方法的是,会区分大小写查找,而且使用反射遍历所有的符号 和值,这样降低了程序 的性能, 所以推荐 手动写方法,检查每个可能的值,这样程序的性能会更好。 还有使用这个方法的时候,也要考虑 夸程序集引用 造成的 版本问题,因为符号编译后是一个常量!

二、位标志

先了解一下 Flags特性,这个特性是对组合位标志的一个展示功能,

c# 枚举和位标志

c# 枚举和位标志


这是一个加了flags 特性跟没有加的区别

 | 和& 和^ 这三个符号是位标志的核心

c# 枚举和位标志

1  、“|” 并集      是对两个数字进行二进制进行合并的运算操作,

c# 枚举和位标志

上面两个二进制的数字  1和5 ,因为第一位 两个都有1 ,所以第一位是1 ,第三位 5 是 1, 所以也是1 ,“|”运算后变成000101 等于5 ,记住有1的地方都是1   

2. &  交集

根据上图位运算,交集得到的数值 是 1

3.^  差集

根据上图位运算,差值得到的数值 是 4

位运算就是根据二进制 0和1来计算的。

这个小弟的见解,如有疑问欢迎一起讨论!