开源 - Ideal库 - 常用枚举扩展方法(一)

embedded/2024/11/14 12:17:03/

今天和大家享一些关于枚举操作相关的常用扩展方法。

在这里插入图片描述

我们平时用的比较多的是正常枚举,同时还有加[Flags]特性的位标志枚举,因此以下所有扩展方法同时适用正常枚举以及位标志枚举。

我们首先定义两种枚举用于下面扩展方法测试适用,代码如下:

//正常枚举
internal enum StatusEnum
{[Description("正常")]Normal = 0,[Description("待机")]Standby = 1,[Description("离线")]Offline = 2,Online = 3,
}
//位标志枚举
[Flags]
internal enum TypeFlagsEnum
{[Description("Http协议")]Http = 1,[Description("Udp协议")]Udp = 2,[Description("Http协议,Udp协议")]HttpAndUdp = 3,[Description("Tcp协议")]Tcp = 4,
}

01、根据枚举名称转换成枚举

该方法接收枚举名称字符串,并转为对应枚举,转换失败则返回空。

首先会校验字符串是否为整数值类型字符串,如果是则直接返回空,因为枚举名称不可能是整数类型字符串。

然后调用TryParse方法进行转换,具体代码如下:

//根据枚举名称转换成枚举,转换失败则返回空
public static T? ToEnumByName<T>(this string name) where T : struct, Enum
{//如果为整数类型字符串,则直接返回空if (int.TryParse(name, out _)){return default;}//转换成功则返回结果,否则返回空if (Enum.TryParse<T>(name, out var result)){return result;}return default;
}

下面我们对其进行详细的单元测试,分别针对正常枚举和位标志枚举两种情况测试,具体用例如下:

(1) 正常枚举名称字符串,成功转换成枚举;

(2) 不存在的枚举名称字符串,返回空;

(3) 整数类型的字符串,返回空;

(4) 正常位标志枚举名称字符串,成功转换成枚举;

(5) 不存在的位标志枚举名称字符串,返回空;

(6) 正常的位标志枚举名称组合字符串,成功转换成枚举;

(7) 不存在的位标志枚举名称组合字符串,返回空;

位标志枚举名称组合字符串是指两个枚举项组合的情况,这也是位标志枚举特色,不了解位标志枚举的可以自行先补充一下相关知识点。

具体代码如下:

[Fact]
public void ToEnumByName()
{//正常枚举名称字符串,成功转换成枚举var status = "Standby".ToEnumByName<StatusEnum>();Assert.Equal(StatusEnum.Standby, status);//不存在的枚举名称字符串,返回空var isStatusNull = "StandbyNull".ToEnumByName<StatusEnum>();Assert.Null(isStatusNull);//整数类型的字符串,返回空var isStatusNullInt = "3".ToEnumByName<StatusEnum>();Assert.Null(isStatusNullInt);//正常位标志枚举名称字符串,成功转换成枚举var flags = "HttpAndUdp".ToEnumByName<TypeFlagsEnum>();Assert.Equal(TypeFlagsEnum.HttpAndUdp, flags);//不存在的位标志枚举名称字符串,返回空var isFlagsNull = "HttpAndUdpNull".ToEnumByName<TypeFlagsEnum>();Assert.Null(isFlagsNull);//正常的位标志枚举名称组合字符串,成功转换成枚举var flagsGroup = "Http,Tcp".ToEnumByName<TypeFlagsEnum>();Assert.Equal(TypeFlagsEnum.Http | TypeFlagsEnum.Tcp, flagsGroup);//不存在的位标志枚举名称组合字符串,返回空var isFlagsGroupNull = "Http,Tcp,Null".ToEnumByName<TypeFlagsEnum>();Assert.Null(isFlagsGroupNull);
}

02、根据枚举名称转换成枚举或默认值

该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,具体代码如下:

//根据枚举名称转换成枚举,转换失败则返回默认枚举
public static T ToEnumOrDefaultByName<T>(this string name, T defaultValue) where T : struct, Enum
{//调用根据枚举名称转换成枚举方法var result = name.ToEnumByName<T>();if (result.HasValue){return result.Value;}//转换失败则返回默认值return defaultValue;
}

因为该方法调用了上一个方法,因此我们就简单测试一下,转换成功返回正确的值,转换失败则返回默认值,具体代码如下:

[Fact]
public void ToEnumOrDefaultByName()
{//正常枚举名称字符串,成功转换成枚举var status = "Standby".ToEnumOrDefaultByName(StatusEnum.Normal);Assert.Equal(StatusEnum.Standby, status);//不存在的枚举名称字符串,返回指定默认值var statusDefault = "StandbyNull".ToEnumOrDefaultByName(StatusEnum.Standby);Assert.Equal(StatusEnum.Standby, statusDefault);
}

03、根据枚举描述转换成枚举

该方法接收枚举描述字符串,并转为对应枚举,转换失败则返回空,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:

//根据枚举描述转换成枚举,转换失败返回空
public static T? ToEnumByDesc<T>(this string description) where T : struct, Enum
{//首先获取枚举所有项foreach (Enum value in Enum.GetValues(typeof(T))){//取枚举项描述与目标描述相比较,相同则返回该枚举项if (value.ToEnumDesc() == description){return (T)value;}}//未查到匹配描述则返回默认值return default;
}

其中ToEnumDesc方法下文会详细讲解。

我们针对该方法进行以下五种情况进行单元测试:

(1) 正常枚举描述字符串,成功转换成枚举;

(2) 如果枚举项没有枚举描述,则枚举名称字符串,成功转换成枚举;

(3) 不存在的枚举描述字符串,返回空;

(4) 正常位标志枚举描述字符串,成功转换成枚举;

(5) 不存在的位标志枚举描述字符串转换,返回空;

具体代码如下:

[Fact]
public void ToEnumByDescription()
{//正常枚举描述字符串,成功转换成枚举var status = "待机".ToEnumByDesc<StatusEnum>();Assert.Equal(StatusEnum.Standby, status);//如果枚举项没有枚举描述,则枚举名称字符串,成功转换成枚举var statusNotDesc = "Online".ToEnumByDesc<StatusEnum>();Assert.Equal(StatusEnum.Online, statusNotDesc);//不存在的枚举描述字符串,返回空var isStatusNull = "待机无".ToEnumByDesc<StatusEnum>();Assert.Null(isStatusNull);//正常位标志枚举描述字符串,成功转换成枚举var flags = "Http协议,Udp协议".ToEnumByDesc<TypeFlagsEnum>();Assert.Equal(TypeFlagsEnum.HttpAndUdp, flags);//不存在的位标志枚举描述字符串转换,返回空var isFlagsNull = "Http协议Udp协议".ToEnumByDesc<TypeFlagsEnum>();Assert.Null(isFlagsNull);
}

04、根据枚举描述转换成枚举或默认值

该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:

//根据枚举描述转换成枚举,转换失败返回默认枚举
public static T? ToEnumOrDefaultByDesc<T>(this string description, T defaultValue) where T : struct, Enum
{//调用根据枚举描述转换成枚举方法var result = description.ToEnumByDesc<T>();if (result.HasValue){return result.Value;}//未查到匹配描述则返回默认值return defaultValue;
}

同样的我们进行简单的单元测试:

[Fact]
public void ToEnumOrDefaultByDesc()
{//正常枚举描述字符串,成功转换成枚举var status = "待机".ToEnumOrDefaultByDesc(StatusEnum.Offline);Assert.Equal(StatusEnum.Standby, status);//不存在的枚举描述字符串,返回指定默认值var statusDefault = "待机无".ToEnumOrDefaultByDesc(StatusEnum.Offline);Assert.Equal(StatusEnum.Offline, statusDefault);
}

05、根据枚举名称转换成枚举值

该方法接收枚举名字字符串,并转为对应枚举值,转换失败则返回空,具体代码如下:

//根据枚举名称转换成枚举值,转换失败则返回空
public static int? ToEnumValueByName<T>(this string name) where T : struct, Enum
{//调用根据枚举名称转换成枚举方法var result = name.ToEnumByName<T>();if (result.HasValue){return Convert.ToInt32(result.Value);}//转换失败则返回空return default;
}

我们对其进行以下五种情况做详细的单元测试:

(1) 正常枚举名称字符串,成功转换成枚举值;

(2) 不存在的枚举名称字符串,返回空;

(3) 正常位标志枚举名称字符串,成功转换成枚举值;

(4) 正常的位标志枚举名称组合字符串,成功转换成枚举值;

(5) 不存在的位标志枚举Int值转换则返回空;

具体代码如下:

[Fact]
public void ToEnumValueByName()
{//正常枚举名称字符串,成功转换成枚举值var status = "Standby".ToEnumValueByName<StatusEnum>();Assert.Equal(1, status);//不存在的枚举名称字符串,返回空var isStatusNull = "StandbyNull".ToEnumValueByName<StatusEnum>();Assert.Null(isStatusNull);//正常位标志枚举名称字符串,成功转换成枚举值var flags = "HttpAndUdp".ToEnumValueByName<TypeFlagsEnum>();Assert.Equal(3, flags);//正常的位标志枚举名称组合字符串,成功转换成枚举值var flagsGroup = "Http,Udp".ToEnumValueByName<TypeFlagsEnum>();Assert.Equal(3, flagsGroup);//不存在的位标志枚举名称字符串,返回空var isFlagsNull = "HttpUdp".ToEnumValueByName<TypeFlagsEnum>();Assert.Null(isFlagsNull);
}

06、根据枚举名称转换成枚举值或默认值

该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,具体代码如下:

//根据枚举名称转换成枚举值,转换失败则返回默认枚举值
public static int ToEnumValueOrDefaultByName<T>(this string name, int defaultValue) where T : struct, Enum
{//根据枚举名称转换成枚举值var result = name.ToEnumValueByName<T>();if (result.HasValue){return result.Value;}//转换失败则返回默认值return defaultValue;
}

我们进行简单的单元测试,具体代码如下:

[Fact]
public void ToEnumValueOrDefaultByName()
{//正常枚举名称字符串,成功转换成枚举值var status = "Standby".ToEnumValueOrDefaultByName<StatusEnum>(2);Assert.Equal(1, status);//不存在的枚举名称字符串,返回指定默认值var statusDefault = "StandbyNull".ToEnumValueOrDefaultByName<StatusEnum>(2);Assert.Equal(2, statusDefault);
}

07、根据枚举名称转换成枚举描述

该方法接收枚举名字字符串,并转为对应枚举描述,转换失败则返回空,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:

//根据枚举名称转换成枚举描述,转换失败则返回空
public static string? ToEnumDescByName<T>(this string name) where T : struct, Enum
{//调用根据枚举名称转换成枚举方法var result = name.ToEnumByName<T>();if (result.HasValue){//转为枚举描述return result.Value.ToEnumDesc();}//转换失败则返回空return default;
}

因为该方法内部都是调用现有方法,因此做个简单单元测试,具体代码如下:

[Fact]
public void ToEnumDescByName()
{//正常位标志枚举名称字符串,成功转换成枚举描述var flags = "HttpAndUdp".ToEnumDescByName<TypeFlagsEnum>();Assert.Equal("Http协议,Udp协议", flags);//正常的位标志枚举名称组合字符串,组合项存在,成功转换成枚举描述var flagsGroup = "Http,Udp".ToEnumDescByName<TypeFlagsEnum>();Assert.Equal("Http协议,Udp协议", flagsGroup);//正常的位标志枚举名称组合字符串,组合项不存在,成功转换成枚举描述var flagsGroup1 = "Http,Tcp".ToEnumDescByName<TypeFlagsEnum>();Assert.Equal("Http协议,Tcp协议", flagsGroup1);
}

08、根据枚举名称转换成枚举描述或默认值

该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举描述,具体代码如下:

//根据枚举名称转换成枚举描述,转换失败则返回默认枚举描述
public static string ToEnumDescOrDefaultByName<T>(this string name, string defaultValue) where T : struct, Enum
{//调用根据枚举名称转换成枚举描述方法var result = name.ToEnumDescByName<T>();if (!string.IsNullOrWhiteSpace(result)){return result;}//转换失败则返回默认枚举描述return defaultValue;
}

做个简单单元测试,具体代码如下:

[Fact]
public void ToEnumDescOrDefaultByName()
{//正常枚举名称字符串,成功转换成枚举描述var status = "Standby".ToEnumDescOrDefaultByName<StatusEnum>("测试");Assert.Equal("待机", status);//不存在的枚举名称字符串,返回指定默认枚举描述var statusDefault = "StandbyNull".ToEnumDescOrDefaultByName<StatusEnum>("测试");Assert.Equal("测试", statusDefault);
}

稍晚些时候我会把库上传至Nuget,大家可以直接使用Ideal.Core.Common。

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Ideal


http://www.ppmy.cn/embedded/137197.html

相关文章

Linux内核编程(二十)RTC子系统一驱动rx8010

本文目录 一、基础知识点1.什么是RTC&#xff1f;2. RTC方案3. 电路原理图 二、RTC芯片&#xff08;RX8010&#xff09;移植三、关于时间的一些命令四、应用层使用1. 使用RTC驱动2. 使用time.h库&#xff08;额外知识点&#xff09; 一、基础知识点 1.什么是RTC&#xff1f; R…

Excel 无法打开文件

Excel 无法打开文件 ‘新建 Microsoft Excel 工作表.xlsx",因为 文件格式或文件扩展名无效。请确定文件未损坏&#xff0c;并且文件扩展名与文件的格式匹配。 原因是卸载WPS之后&#xff0c;注册表未修改过来。 重新下载WPS&#xff0c;新建&#xff0c;xls工作表&#x…

Vue3 -- 新组件【谁学谁真香系列6】

Teleport Teleport是什么?–Teleport是一种能够将我们的组件html结构移动到指定位置的技术。 父组件: <template><div calss="outer"><h2>我是App组件</h2><img src="https://z1.ax1x.com/2023/11/19/piNxLo4.jpg" alt=&qu…

Prompt Engineering Guide

文章目录 Prompt Engineering Guide提示工程简介基本概念包含要素要避免不明确的prompt技术关注做了什么&#xff0c;不要关注不做什么角色提示Role Prompting 提示技术CoT生成的知识作为预测的知识库判断的一部分Prompting ChainingToT思维链检索增强RAGPrompt策略分析 提示应…

STM32WB55RG开发(3)----生成 BLE 程序连接手机APP

STM32WB55RG开发----3.生成 BLE 程序连接手机APP 概述硬件准备视频教学样品申请源码下载参考程序选择芯片型号配置时钟源配置时钟树RTC时钟配置RF wakeup时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙设置工程信息工程文件设置结果演示 概述 本项目旨…

探索深度学习的本质

深度学习的本质是利用多层&#xff08;深层&#xff09;的神经网络结构来从数据中学习复杂的模式和特征。其主要特点是具有层次结构&#xff0c;能够实现自动特征提取。非线性、可扩展性和迁移学习能力是深度学习能够处理复杂问题和广泛&#xff08;低成本&#xff09;应用的关…

使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径

在进行WPF开发时&#xff0c;System.Windows.Forms.FolderBrowserDialog的选择文件夹功能不支持输入路径&#xff1a; 希望能够获得下图所示的选择文件夹功能&#xff1a; 于是&#xff0c;通过NuGet中安装Ookii.Dialogs.Wpf包&#xff0c;并创建一个简单的工具类&#xff1a; …

计算机毕业设计Python流量检测可视化 DDos攻击流量检测与可视化分析 SDN web渗透测试系统 网络安全 信息安全 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…