【C#基础概念】枚举 (enum详解)

您所在的位置:网站首页 蛟字的多种写法 【C#基础概念】枚举 (enum详解)

【C#基础概念】枚举 (enum详解)

2024-01-17 22:14| 来源: 网络整理| 查看: 265

我们重点来讲解 简单枚举和标志枚举的用法和区别

继承

Object-> ValueType ->Enum Object-> ValueType ->struct 包括int float等简单值类型 Object-> ValueType ->ValueTuple Object-> ValueType ->Nullable

 

枚举的简介:

1、枚举类型 是由基础整型数值类型的一组命名常量定义的值类型。

2.枚举使用enum关键字来声明, 枚举可以和类并列也可以  写在类里面,不能写在方法里。

namespace ConsoleApp1 { class Program { //////////////省略。。。。。。。。。 } [Flags] enum Man { //////////////省略。。。。。。。。。 } }

3、枚举都是隐式密封的(sealed),不允许作为基类派生子类。枚举里面的成员只能是默认公共的静态的(public、static),不能有访问修饰符;枚举本身一般不加访问修饰符,要加的话只能是internal

    或public;

4、枚举成员是常量 不可更改。可以当作字段来用。由于枚举成员在编译时将被替换为字面量,使得其成员取值类型受到了一定限制。   public readonly int SOU = 12; public const int seiu = 12; enum n { i=0} 编译后的iL代码 .field public initonly int32 SOU .field public static literal int32 seiu = int32(12) .field public static literal valuetype Galaxy.Program/n i = int32(0) //枚举中字段IL代码和Const 常量定义的IL代码是一样的,编译时常数,在编译时是已知的,在程序的生命周期内不会改变

 

5、默认情况下,枚举成员的关联常数值为类型 int(被编译查成IL:.field public specialname rtspecialname int32 value__) ;它们从零开始,并按定义文本顺序递增 1。 可以显式指定任何其他整数数值类型作为枚举类型的基础类型。 还可以显式指定关联的常数值,如下面的示例所示: enum ErrorCode : int //不是继承,只是写法像继承,查看IL代码 被编译成.field public specialname rtspecialname int32 value__,如果是继承应该显示extends { None = 0, Unknown = 1, ConnectionLost = 100, OutlierReading = 200 }

 

6、枚举元素不可以重复,枚举元素的值可以重复。最后一个元素后的逗号可有可无。枚举最后的冒号可有可无。 7、 基础类型指定为每个枚举数分配的存储大小。     System.Enum 类型和枚举约束 System.Enum 类型是所有枚举类型的抽象基类。 它提供多种方法来获取有关枚举类型及其值的信息。 有关更多信息和示例,请参阅 System.Enum API 参考页。从 C# 7.3 开始,你可以在基类约束中使用 System.Enum (称为枚举约束),以指定类型参数为枚举类型。 所有枚举类型也都满足 struct 约束,此约束用于指定类型参数为不可为 null 的值类型。 转换 对于任何枚举类型,枚举类型与其基础整型类型之间存在显式转换。 如果将枚举值转换为其基础类型,则结果为枚举成员的关联整数值。 public enum Season { Spring, Summer, Autumn, Winter } public class EnumConversionExample { public static void Main() { Season a = Season.Autumn; Console.WriteLine($"Integral value of {a} is {(int)a}"); // output: Integral value of Autumn is 2 var b = (Season)1; Console.WriteLine(b); // output: Summer } }

使用 Enum.IsDefined 方法来确定枚举类型是否包含具有特定关联值的枚举成员。对于任何枚举类型,都存在分别与 System.Enum 类型的装箱和取消装箱相互转换。

  1、简单枚举:枚举变落表示一个成员;

 

 

 

 

 

枚举类型的作用是限制其变量只能从有限的选项中取值,这些选项(枚举类型的成员)各自对应于一个数字,数字默认从 0 开始,并以此递增。例如:

public enum Days{ Sunday, Monday, Tuesday, // ...}

其中 Sunday 的值是 0,Monday 是 1,以此类推。为了一眼能看出每个成员代表的值,一般推荐显示地将成员值写出来,不要省略:

public enum Days{ Sunday = 0, Monday = 1, Tuesday = 2, // ...}

C# 枚举成员的类型默认是 int 类型,通过继承可以声明枚举成员为其它类型,比如:

publicenum Days : byte{ Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7}

枚举类型一定是继承自 byte、sbyte、short、ushort、int、uint、long 和 ulong 中的一种,不能是其它类型。下面是几个枚举的常见用法(以上面的 Days 枚举为例):

// 枚举转字符串string foo = Days.Saturday.ToString(); // "Saturday"string foo = Enum.GetName(typeof(Days), 6); // "Saturday"// 字符串转枚举Enum.TryParse("Tuesday", out Days bar); // true, bar = Days.Tuesday(Days)Enum.Parse(typeof(Days), "Tuesday"); // Days.Tuesday

// 枚举转数字byte foo = (byte)Days.Monday; // 1// 数字转枚举Days foo = (Days)2; // Days.Tuesday

// 获取枚举所属的数字类型Type foo = Enum.GetUnderlyingType(typeof(Days))); // System.Byte

// 获取所有的枚举成员Array foo = Enum.GetValues(typeof(MyEnum);// 获取所有枚举成员的字段名string[] foo = Enum.GetNames(typeof(Days));

另外,值得注意的是,枚举可能会得到非预期的值(值没有对应的成员)。比如:

Days d = (Days)21; // 不会报错Enum.IsDefined(typeof(Days), d); // false

即使枚举没有值为 0 的成员,它的默认值永远都是 0。

var z = default(Days); // 0

枚举可以通过 Description、Display 等特性来为成员添加有用的辅助信息,比如:

public enum ApiStatus { [Description("成功")] OK = 0, [Description("资源未找到")] NotFound = 2, [Description("拒绝访问")] AccessDenied = 3 } static class EnumExtensions { public static string GetDescription(this Enum val) { var field = val.GetType().GetField(val.ToString()); var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)); if (customAttribute == null) { return val.ToString(); } else { return ((DescriptionAttribute)customAttribute).Description; } } } static void Main(string[] args) { Console.WriteLine(ApiStatus.Ok.GetDescription()); // "成功" }

上面这些我认为已经包含了大部分我们日常用到的枚举知识了。下面我们继续回到文章开头说的用户角色存储问题。

 

2、标记枚举:枚举变量可以表示一个集合,每当可枚举表示可能值的集合而不是单个值时,应使用[Flags]属性

 

  2.1 标志枚举的使用准则

避免创建标志枚举,其中某些值的组合无效。

 避免使用值为零的标记枚举值,除非该值表示 "所有标志均已清除" 并正确命名,如下一个准则所述。

✔️ DO name 标记枚举的零值 None 。 对于标志枚举,值始终为 "清除所有标志"。

 

 

2.2三种写法都是等效的;

第一种写法:位数大了以后不容易察觉错误;

第二中写法:推荐,容易理解 标志枚举是如何运作的。

第三种写法:容易阅读,但是有个bug,当移位超出整形限制范围时候,编译器不会报错,计算结果失效。曹操不是兄弟,但是在int整型范围之下 1



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3