C#枚举(一)使用总结以及扩展类分享

摘要:
如果没有显式声明基本类型,那么在Int32的实际开发过程中,使用枚举可以使代码更清晰、更优雅。最近,我对枚举的使用进行了总结和整理,发现了一些有趣的知识盲点。接下来,我们将简要介绍开发过程中枚举的常见内容以及扩展类的共享。默认情况下,用于枚举的内存由公共语言运行库初始化为零。因此,如果没有定义值为零的常量,则在创建枚举时,该枚举将包含非法值。

0.介绍

枚举是一组命名常量,其基础类型为任意整型。 如果没有显式声明基础类型, 则为Int32

在实际开发过程中,枚举的使用可以让代码更加清晰且优雅。

最近在对枚举的使用进行了一些总结与整理,也发现了一些很有意思的知识盲区。

接下来先简单为大家介绍枚举在开发过程中的常用内容以及扩展类的分享。如果喜欢直接看代码的可以查看最后的样例源码。

1. 参考资料

官方Doc https://docs.microsoft.com/zh-cn/dotnet/api/system.enum?view=net-5.0

博客 https://www.cnblogs.com/kissdodog/archive/2013/01/16/2863515.html

博客 https://www.cnblogs.com/willick/p/csharp-enum-superior-tactics.html

2.核心内容

  • 枚举的使用心得

0.枚举数值在开发过程中一旦确定不允许更改(除非必要 )

1.在定义枚举的时候要设置0值,且不作为有效的业务值。(不作为有效值的原因是枚举的初始化值为零,在没有正确赋值的情况下,已经有默认值可能会造成困扰,所以直接不使用0作为业务有效值,可以省去不必要的麻烦,这半点纯属个人建议~)

这一点官方文档也有“最佳做法”的建议。

如果未定义值为0的枚举成员,则考虑创建 None 枚举常数。 默认情况下,由公共语言运行时将用于枚举的内存初始化为零。 因此,如果未定义值为零的常量,则在创建枚举时将包含非法值。

2.在前后端交互过程中,如果后端接收的对象中包含枚举的话,需要将枚举属性定义成可空枚举,否则前端数据有可能(前端属性值在后端的枚举值中匹配不上时)无法传输到后端。

3.数据库保存枚举值而非枚举属性字符串

虽然保存枚举属性字符串会更加直观,但是不利于后续枚举字符串重命名,且字符串长度限制也制约着枚举的命名...

  • 枚举的基本用法

定义枚举

枚举并不显式从继承 Enum ; 继承关系由编译器隐式处理

// 枚举YesOrNo
public enum YesOrNo
{
    [Description("")]
    None = 0,
    [Description("")]
    Yes = 1,
    [Description("")]
    No = 2
}
// 枚举YesOrNo 基础类型为byte
public enum YesOrNo_Byte : byte
{
    [Description("")]
    None = 0,
    [Description("")]
    Yes = 1,
    [Description("")]
    No = 2
}
枚举 => 转字符串
string yesString = YesOrNo.Yes.ToString(); // Yes
枚举 => 转数字
int yesInt = (int)YesOrNo.Yes; // 1
字符串 => 枚举
YesOrNo yesOrNo_Yes = (YesOrNo)Enum.Parse(typeof(YesOrNo), "Yes"); // YesOrNo.Yes
数字 => 枚举
YesOrNo yesOrNo_No = (YesOrNo)2; // YesOrNo.No
获取所有的枚举成员
Array yesOrNos = Enum.GetValues(typeof(YesOrNo)); // [YesOrNo.None,YesOrNo.Yes,YesOrNo.No]
获取所有枚举成员的属性名
string[] yesOrNoNames = Enum.GetNames(typeof(YesOrNo)); // ["None","Yes","No"]
获取枚的举基础类型
Type typeInt = Enum.GetUnderlyingType(typeof(YesOrNo)); // System.Int32
    
Type typeByte = Enum.GetUnderlyingType(typeof(YesOrNo_Byte)); // System.Byte
扩展方法
字符串 => 转枚举
// GetEnum()  字符串 => 转枚举
var yesString = "Yes".GetEnum<YesOrNo>(); // YesOrNo.Yes

/// <summary>
/// 根据字符串转成指定枚举值
/// </summary>
public static T GetEnum<T>(this string enumString)
{
    return (T)Enum.Parse(typeof(T), enumString);
}
枚举 => 转数字
// GetIntValue() 枚举 => 转数字
int yesInt = YesOrNo.Yes.GetIntValue(); // 1

/// <summary>
/// 获取枚举的值
/// </summary>
public static int GetIntValue(this Enum value)
{
    return Convert.ToInt32(value);
}            
获取枚举的描述
// GetDescription()  获取枚举的描述
var description = YesOrNo.Yes.GetDescription(); //

/// <summary>
/// 根据枚举获取枚举描述
/// </summary>
public static string GetDescription(this Enum value)
{
    var field = value.GetType().GetField(value.ToString());
    var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
    if (customAttribute == null)
        return value.ToString();
    else
        return ((DescriptionAttribute)customAttribute).Description;
}          
将枚举字符串值与描述转字典
// GetEnumDescriptions() 获取枚举字符串值与描述
var dictionary = typeof(YesOrNo).GetEnumDescriptions(); // {{[None, ""]},{[Yes, 是]},{[No, 否]}}

/// <summary>
/// 获取枚举字符串值及描述值的字典
/// </summary>

public static IDictionary<string, string> GetEnumDescriptions(this Type enumType)
{
    var dictionary = new Dictionary<string, string>();
    foreach (Enum code in Enum.GetValues(enumType))
        dictionary.Add(code.ToString(), code.GetDescription());

    return dictionary;
}         
将枚举值与描述转字典
// GetEnumIntDescriptions() 获取枚举值与描述
var intDictionary = typeof(YesOrNo).GetEnumIntDescriptions(); // {{[0, ""]},{[1, 是]},{[2, 否]}}

/// <summary>
/// 获取枚举值及描述值的字典
/// </summary>

public static IDictionary<int, string> GetEnumIntDescriptions(this Type enumType)
{
    var dictionary = new Dictionary<int, string>();
    foreach (Enum code in Enum.GetValues(enumType))
        dictionary.Add(code.GetIntValue(), code.GetDescription());

    return dictionary;
}       

3.样例源码地址

https://github.com/Impartsoft/Bins/tree/main/EnumDemo

免责声明:文章转载自《C#枚举(一)使用总结以及扩展类分享》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Apache POI Java读取100万行Excel性能优化:split vs indexOf+subString,谁性能好Guava LoadingCache不能缓存null值下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

iOS 枚举类型学习

一,两者的用法 枚举类型定义用关键字enum标识,形式为:enum 标识符{ 枚举数据表 };枚举数据(枚举常量)是一些特定的标识符,标识符代表什么含义,完全由程序员决定。数据枚举的顺序规定了枚举数据的序号,从0开始,依次递增。enum status{ copy, delete };枚举类型status仅有两个数据,一个是copy,一个是delete,序号...

Xcode 报错:duplicate symbols for architecture x86_64错误分析及解决

1、参与编译的.m文件重复导入。一般是手动往工程中导入源文件时导入在了不同的目录。 解决方法也很简单,在 Target -> build parses -> complie sources,去掉重复的文件即可。 2、导入头文件时,误写为导入.m 文件 即 #import xxx.h 写成了 #import xxx.m 解决方法就是,导入头文...

《深入浅出WPF》学习笔记二数据绑定(Binding)、依赖属性和附加属性

第六章 深入浅出话Binding    1、绑定的源可以是任意对象,并通过属性公开自己的数据;         绑定的目标必须是依赖对象的依赖属性。    2、INotifyPropertyChanged接口,当对象实现了这个接口的时候,当数据源改变的时候可以通知UI同时实现改变,         实现原理:当为Binding设置了数据源后,Bindin...

ADO.NET基础必备之SqlParameterCollection 类

SqlParameterCollection 类 表示与 SqlCommand 相关联的参数的集合以及各个参数到 DataSet 中列的映射。无法继承此类。 语法:  [ListBindableAttribute(false)] public sealed class SqlParameterCollection : DbParameterCollecti...

十五.ProtoBuf3的基础总结

转自:https://blog.csdn.net/u011518120/article/details/54604615 定义一个消息类型 指定字段类型 分配标识号 指定字段规则 添加更多消息类型 添加注释 保留标识符(Reserved) 从.proto文件生成了什么? 标量数值类型 默认值 枚举 使用其他消息类型 导入定义 使用proto2消息...

[Java核心技术]五-继承(枚举类)

Java枚举类型(enum) 枚举类型都是继承了Enum类(是一个抽象类)的一个类,我们可以向enum类中添加方法和变量等。编译再反编译可以看到枚举类型对应的类的内容。 每个枚举常量都对应一个Enum类的实例。 例子 public enum Day2 { MONDAY("星期一"), TUESDAY("星期二"), WEDNES...