- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
今天和大家享一些关于枚举操作相关的常用扩展方法.
我们平时用的比较多的是正常枚举,同时还有加[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,
}
该方法接收枚举名称字符串,并转为对应枚举,转换失败则返回空.
首先会校验字符串是否为整数值类型字符串,如果是则直接返回空,因为枚举名称不可能是整数类型字符串.
然后调用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);
}
该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,具体代码如下:
//根据枚举名称转换成枚举,转换失败则返回默认枚举
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);
}
该方法接收枚举描述字符串,并转为对应枚举,转换失败则返回空,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:
//根据枚举描述转换成枚举,转换失败返回空
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);
}
该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:
//根据枚举描述转换成枚举,转换失败返回默认枚举
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);
}
该方法接收枚举名字字符串,并转为对应枚举值,转换失败则返回空,具体代码如下:
//根据枚举名称转换成枚举值,转换失败则返回空
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);
}
该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举值,具体代码如下:
//根据枚举名称转换成枚举值,转换失败则返回默认枚举值
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);
}
该方法接收枚举名字字符串,并转为对应枚举描述,转换失败则返回空,其中如果枚举项没有描述则以枚举名称代替,具体代码如下:
//根据枚举名称转换成枚举描述,转换失败则返回空
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);
}
该方法是对上一个方法的补充,用于处理转换不成功时,则返回一个指定默认枚举描述,具体代码如下:
//根据枚举名称转换成枚举描述,转换失败则返回默认枚举描述
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 。
最后此篇关于开源-Ideal库-常用枚举扩展方法(一)的文章就讲到这里了,如果你想了解更多关于开源-Ideal库-常用枚举扩展方法(一)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
所以,Fizz Buzz 是一个非常简单的问题,这个问题有很多解决方案。在最近的一次采访中,面试官让我为 Fizz Buzz 写一个函数,所以我一手想出了以下方法。 void fizz_buzz(in
我正在设计一个游戏,其中一个角色有很多元素,而这些元素可以有多种类型。有一个角色表,以及十二个按类型(例如武器、盔甲和各种其他项目类型)分割的可能项目的不同表。 我想制作一个表来保存这些项目类型的实例
我正在尝试分析/分析核心 JAVA 应用程序。 我正在使用 JConsole Eclipse MAT 。 我在 Perm-Gen 图表中观察到以下情况(在 Windows XP 计算机上记录的 1 小
我一直在创建一个网站以链接到与 IDEAL 的高级集成。问题是当我创建自签名证书并将它们加载到站点时,我收到此错误: 失败签名数据:错误:0906A068:PEM 例程:PEM_do_header:错
我的数据大约是300G。如果我使用 Hadoop 对其执行 reduce 作业,180 个 reduce 插槽就可以了,队列中没有任务等待。 如果我使用具有相同数量的 reduce 槽的 Spark
全文MATCH 给出索引表中所有记录的相对相关性。但是,我根据测试样本和恒定样本(我与之比较)之间的相似度(假设 <70% 不足以将其视为匹配)做出决定。 之前我使用 Levenshtein Dist
尝试从理想表单中删除验证规则,但无法摆脱它!。当值小于 3 时,我添加规则来验证 4 个额外字段,但当我输入的值大于 3 时,我希望删除此验证。我一直试图在 else 语句内添加但不起作用。请帮忙 $
我正在使用 pscl R 中的包并试图让它产生可测试/可重复的结果。我查看了底层的 C 代码,看起来好像 GetRNGstate()和 PutRNGstate()在正确的地方被调用,但似乎不可能重复来
我正在尝试实现 iDeal payment使用 stripe 的方法在我的flutter app ,但我被困住了。 What i have tried: RaisedButton(
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 8 年前。 Improv
我想在我的应用程序中集成 Adyen 支付网关,并且可以接受 PayPal 和 iDeal 付款方式。如何将它与 iOS 原生应用集成? 我查看了他们的文档和 github 示例,但没有找到任何方法。
我已经根据本教程制作了应用程序:https://stripe.com/docs/checkout/express 我现在如何将付款方式从信用卡更改为理想付款方式?理想文档:https://stripe
我想知道在处理数据库文件时应该应用的文件处理流。我想创建一个数据库文件,即一个包含内容并且可以编辑这些内容的文件 例如-假设文件包含如下数据 Harshul 97 Jack 42 Sergey 6
我想从健康应用中获取/读取数据。使用 HealthDataResolver.AggregateRequest 读取不同的数据值,例如总步数和距离。 下面是工作代码,我得到了 startTime 和 e
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 4年前关闭。
嗨,我有一个使用 mysql 的 php 网站,并且有一个表,其中有一列名为“名称”。我希望它具有以下功能: 它应该是 varchar(N) 类型,就像常规名称一样。 它可能很长,但绝对不应该包含所谓
我是一名优秀的程序员,十分优秀!