ToB企服应用市场:ToB评测及商务社交产业平台

标题: 开源 - Ideal库 - 常用罗列扩展方法(一) [打印本页]

作者: 汕尾海湾    时间: 2024-11-13 00:37
标题: 开源 - Ideal库 - 常用罗列扩展方法(一)
本日和大家享一些关于罗列操纵相关的常用扩展方法。

我们平时用的比力多的是正常罗列,同时另有加[Flags]特性的位标志罗列,因此以下所有扩展方法同时适用正常罗列以及位标志罗列。
我们起首定义两种罗列用于下面扩展方法测试适用,代码如下:
  1. //正常枚举
  2. internal enum StatusEnum
  3. {
  4.     [Description("正常")]
  5.     Normal = 0,
  6.     [Description("待机")]
  7.     Standby = 1,
  8.     [Description("离线")]
  9.     Offline = 2,
  10.     Online = 3,
  11. }
  12. //位标志枚举
  13. [Flags]
  14. internal enum TypeFlagsEnum
  15. {
  16.     [Description("Http协议")]
  17.     Http = 1,
  18.     [Description("Udp协议")]
  19.     Udp = 2,
  20.     [Description("Http协议,Udp协议")]
  21.     HttpAndUdp = 3,
  22.     [Description("Tcp协议")]
  23.     Tcp = 4,
  24. }
复制代码
01、根据罗列名称转换成罗列

该方法接收罗列名称字符串,并转为对应罗列,转换失败则返回空。
起首会校验字符串是否为整数值范例字符串,如果是则直接返回空,因为罗列名称不可能是整数范例字符串。
然后调用TryParse方法进行转换,具体代码如下:
  1. //根据枚举名称转换成枚举,转换失败则返回空
  2. public static T? ToEnumByName<T>(this string name) where T : struct, Enum
  3. {
  4.     //如果为整数类型字符串,则直接返回空
  5.     if (int.TryParse(name, out _))
  6.     {
  7.         return default;
  8.     }
  9.     //转换成功则返回结果,否则返回空
  10.     if (Enum.TryParse<T>(name, out var result))
  11.     {
  12.         return result;
  13.     }
  14.     return default;
  15. }
复制代码
下面我们对其进行具体的单元测试,分别针对正常罗列和位标志罗列两种情况测试,具体用比方下:
(1) 正常罗列名称字符串,成功转换成罗列;
(2) 不存在的罗列名称字符串,返回空;
(3) 整数范例的字符串,返回空;
(4) 正常位标志罗列名称字符串,成功转换成罗列;
(5) 不存在的位标志罗列名称字符串,返回空;
(6) 正常的位标志罗列名称组合字符串,成功转换成罗列;
(7) 不存在的位标志罗列名称组合字符串,返回空;
位标志罗列名称组合字符串是指两个罗列项组合的情况,这也是位标志罗列特色,不了解位标志罗列的可以自行先增补一下相关知识点。
具体代码如下:
  1. [Fact]
  2. public void ToEnumByName()
  3. {
  4.     //正常枚举名称字符串,成功转换成枚举
  5.     var status = "Standby".ToEnumByName<StatusEnum>();
  6.     Assert.Equal(StatusEnum.Standby, status);
  7.     //不存在的枚举名称字符串,返回空
  8.     var isStatusNull = "StandbyNull".ToEnumByName<StatusEnum>();
  9.     Assert.Null(isStatusNull);
  10.     //整数类型的字符串,返回空
  11.     var isStatusNullInt = "3".ToEnumByName<StatusEnum>();
  12.     Assert.Null(isStatusNullInt);
  13.     //正常位标志枚举名称字符串,成功转换成枚举
  14.     var flags = "HttpAndUdp".ToEnumByName<TypeFlagsEnum>();
  15.     Assert.Equal(TypeFlagsEnum.HttpAndUdp, flags);
  16.     //不存在的位标志枚举名称字符串,返回空
  17.     var isFlagsNull = "HttpAndUdpNull".ToEnumByName<TypeFlagsEnum>();
  18.     Assert.Null(isFlagsNull);
  19.     //正常的位标志枚举名称组合字符串,成功转换成枚举
  20.     var flagsGroup = "Http,Tcp".ToEnumByName<TypeFlagsEnum>();
  21.     Assert.Equal(TypeFlagsEnum.Http | TypeFlagsEnum.Tcp, flagsGroup);
  22.     //不存在的位标志枚举名称组合字符串,返回空
  23.     var isFlagsGroupNull = "Http,Tcp,Null".ToEnumByName<TypeFlagsEnum>();
  24.     Assert.Null(isFlagsGroupNull);
  25. }
复制代码
02、根据罗列名称转换成罗列或默认值

该方法是对上一个方法的增补,用于处理转换不成功时,则返回一个指定默认罗列值,具体代码如下:
  1. //根据枚举名称转换成枚举,转换失败则返回默认枚举
  2. public static T ToEnumOrDefaultByName<T>(this string name, T defaultValue) where T : struct, Enum
  3. {
  4.     //调用根据枚举名称转换成枚举方法
  5.     var result = name.ToEnumByName<T>();
  6.     if (result.HasValue)
  7.     {
  8.         return result.Value;
  9.     }
  10.     //转换失败则返回默认值
  11.     return defaultValue;
  12. }
复制代码
因为该方法调用了上一个方法,因此我们就简单测试一下,转换成功返回正确的值,转换失败则返回默认值,具体代码如下:
  1. [Fact]
  2. public void ToEnumOrDefaultByName()
  3. {
  4.     //正常枚举名称字符串,成功转换成枚举
  5.     var status = "Standby".ToEnumOrDefaultByName(StatusEnum.Normal);
  6.     Assert.Equal(StatusEnum.Standby, status);
  7.     //不存在的枚举名称字符串,返回指定默认值
  8.     var statusDefault = "StandbyNull".ToEnumOrDefaultByName(StatusEnum.Standby);
  9.     Assert.Equal(StatusEnum.Standby, statusDefault);
  10. }
复制代码
03、根据罗列描述转换成罗列

该方法接收罗列描述字符串,并转为对应罗列,转换失败则返回空,其中如果罗列项没有描述则以罗列名称代替,具体代码如下:
  1. //根据枚举描述转换成枚举,转换失败返回空
  2. public static T? ToEnumByDesc<T>(this string description) where T : struct, Enum
  3. {
  4.     //首先获取枚举所有项
  5.     foreach (Enum value in Enum.GetValues(typeof(T)))
  6.     {
  7.         //取枚举项描述与目标描述相比较,相同则返回该枚举项
  8.         if (value.ToEnumDesc() == description)
  9.         {
  10.             return (T)value;
  11.         }
  12.     }
  13.     //未查到匹配描述则返回默认值
  14.     return default;
  15. }
复制代码
其中ToEnumDesc方法下文会具体讲解。
我们针对该方法进行以下五种情况进行单元测试:
(1) 正常罗列描述字符串,成功转换成罗列;
(2) 如果罗列项没有罗列描述,则罗列名称字符串,成功转换成罗列;
(3) 不存在的罗列描述字符串,返回空;
(4) 正常位标志罗列描述字符串,成功转换成罗列;
(5) 不存在的位标志罗列描述字符串转换,返回空;
具体代码如下:
  1. [Fact]
  2. public void ToEnumByDescription()
  3. {
  4.     //正常枚举描述字符串,成功转换成枚举
  5.     var status = "待机".ToEnumByDesc<StatusEnum>();
  6.     Assert.Equal(StatusEnum.Standby, status);
  7.     //如果枚举项没有枚举描述,则枚举名称字符串,成功转换成枚举
  8.     var statusNotDesc = "Online".ToEnumByDesc<StatusEnum>();
  9.     Assert.Equal(StatusEnum.Online, statusNotDesc);
  10.     //不存在的枚举描述字符串,返回空
  11.     var isStatusNull = "待机无".ToEnumByDesc<StatusEnum>();
  12.     Assert.Null(isStatusNull);
  13.     //正常位标志枚举描述字符串,成功转换成枚举
  14.     var flags = "Http协议,Udp协议".ToEnumByDesc<TypeFlagsEnum>();
  15.     Assert.Equal(TypeFlagsEnum.HttpAndUdp, flags);
  16.     //不存在的位标志枚举描述字符串转换,返回空
  17.     var isFlagsNull = "Http协议Udp协议".ToEnumByDesc<TypeFlagsEnum>();
  18.     Assert.Null(isFlagsNull);
  19. }
复制代码
04、根据罗列描述转换成罗列或默认值

该方法是对上一个方法的增补,用于处理转换不成功时,则返回一个指定默认罗列值,其中如果罗列项没有描述则以罗列名称代替,具体代码如下:
  1. //根据枚举描述转换成枚举,转换失败返回默认枚举
  2. public static T? ToEnumOrDefaultByDesc<T>(this string description, T defaultValue) where T : struct, Enum
  3. {
  4.     //调用根据枚举描述转换成枚举方法
  5.     var result = description.ToEnumByDesc<T>();
  6.     if (result.HasValue)
  7.     {
  8.         return result.Value;
  9.     }
  10.     //未查到匹配描述则返回默认值
  11.     return defaultValue;
  12. }
复制代码
同样的我们进行简单的单元测试:
  1. [Fact]
  2. public void ToEnumOrDefaultByDesc()
  3. {
  4.     //正常枚举描述字符串,成功转换成枚举
  5.     var status = "待机".ToEnumOrDefaultByDesc(StatusEnum.Offline);
  6.     Assert.Equal(StatusEnum.Standby, status);
  7.     //不存在的枚举描述字符串,返回指定默认值
  8.     var statusDefault = "待机无".ToEnumOrDefaultByDesc(StatusEnum.Offline);
  9.     Assert.Equal(StatusEnum.Offline, statusDefault);
  10. }
复制代码
05、根据罗列名称转换成罗列值

该方法接收罗列名字字符串,并转为对应罗列值,转换失败则返回空,具体代码如下:
  1. //根据枚举名称转换成枚举值,转换失败则返回空
  2. public static int? ToEnumValueByName<T>(this string name) where T : struct, Enum
  3. {
  4.     //调用根据枚举名称转换成枚举方法
  5.     var result = name.ToEnumByName<T>();
  6.     if (result.HasValue)
  7.     {
  8.         return Convert.ToInt32(result.Value);
  9.     }
  10.     //转换失败则返回空
  11.     return default;
  12. }
复制代码
我们对其进行以下五种情况做具体的单元测试:
(1) 正常罗列名称字符串,成功转换成罗列值;
(2) 不存在的罗列名称字符串,返回空;
(3) 正常位标志罗列名称字符串,成功转换成罗列值;
(4) 正常的位标志罗列名称组合字符串,成功转换成罗列值;
(5) 不存在的位标志罗列Int值转换则返回空;
具体代码如下:
  1. [Fact]
  2. public void ToEnumValueByName()
  3. {
  4.     //正常枚举名称字符串,成功转换成枚举值
  5.     var status = "Standby".ToEnumValueByName<StatusEnum>();
  6.     Assert.Equal(1, status);
  7.     //不存在的枚举名称字符串,返回空
  8.     var isStatusNull = "StandbyNull".ToEnumValueByName<StatusEnum>();
  9.     Assert.Null(isStatusNull);
  10.     //正常位标志枚举名称字符串,成功转换成枚举值
  11.     var flags = "HttpAndUdp".ToEnumValueByName<TypeFlagsEnum>();
  12.     Assert.Equal(3, flags);
  13.     //正常的位标志枚举名称组合字符串,成功转换成枚举值
  14.     var flagsGroup = "Http,Udp".ToEnumValueByName<TypeFlagsEnum>();
  15.     Assert.Equal(3, flagsGroup);
  16.     //不存在的位标志枚举名称字符串,返回空
  17.     var isFlagsNull = "HttpUdp".ToEnumValueByName<TypeFlagsEnum>();
  18.     Assert.Null(isFlagsNull);
  19. }
复制代码
06、根据罗列名称转换成罗列值或默认值

该方法是对上一个方法的增补,用于处理转换不成功时,则返回一个指定默认罗列值,具体代码如下:
  1. //根据枚举名称转换成枚举值,转换失败则返回默认枚举值
  2. public static int ToEnumValueOrDefaultByName<T>(this string name, int defaultValue) where T : struct, Enum
  3. {
  4.     //根据枚举名称转换成枚举值
  5.     var result = name.ToEnumValueByName<T>();
  6.     if (result.HasValue)
  7.     {
  8.         return result.Value;
  9.     }
  10.     //转换失败则返回默认值
  11.     return defaultValue;
  12. }
复制代码
我们进行简单的单元测试,具体代码如下:
  1. [Fact]
  2. public void ToEnumValueOrDefaultByName()
  3. {
  4.     //正常枚举名称字符串,成功转换成枚举值
  5.     var status = "Standby".ToEnumValueOrDefaultByName<StatusEnum>(2);
  6.     Assert.Equal(1, status);
  7.     //不存在的枚举名称字符串,返回指定默认值
  8.     var statusDefault = "StandbyNull".ToEnumValueOrDefaultByName<StatusEnum>(2);
  9.     Assert.Equal(2, statusDefault);
  10. }
复制代码
07、根据罗列名称转换成罗列描述

该方法接收罗列名字字符串,并转为对应罗列描述,转换失败则返回空,其中如果罗列项没有描述则以罗列名称代替,具体代码如下:
  1. //根据枚举名称转换成枚举描述,转换失败则返回空
  2. public static string? ToEnumDescByName<T>(this string name) where T : struct, Enum
  3. {
  4.     //调用根据枚举名称转换成枚举方法
  5.     var result = name.ToEnumByName<T>();
  6.     if (result.HasValue)
  7.     {
  8.         //转为枚举描述
  9.         return result.Value.ToEnumDesc();
  10.     }
  11.     //转换失败则返回空
  12.     return default;
  13. }
复制代码
因为该方法内部都是调用现有方法,因此做个简单单元测试,具体代码如下:
  1. [Fact]
  2. public void ToEnumDescByName()
  3. {
  4.     //正常位标志枚举名称字符串,成功转换成枚举描述
  5.     var flags = "HttpAndUdp".ToEnumDescByName<TypeFlagsEnum>();
  6.     Assert.Equal("Http协议,Udp协议", flags);
  7.     //正常的位标志枚举名称组合字符串,组合项存在,成功转换成枚举描述
  8.     var flagsGroup = "Http,Udp".ToEnumDescByName<TypeFlagsEnum>();
  9.     Assert.Equal("Http协议,Udp协议", flagsGroup);
  10.     //正常的位标志枚举名称组合字符串,组合项不存在,成功转换成枚举描述
  11.     var flagsGroup1 = "Http,Tcp".ToEnumDescByName<TypeFlagsEnum>();
  12.     Assert.Equal("Http协议,Tcp协议", flagsGroup1);
  13. }
复制代码
08、根据罗列名称转换成罗列描述或默认值

该方法是对上一个方法的增补,用于处理转换不成功时,则返回一个指定默认罗列描述,具体代码如下:
  1. //根据枚举名称转换成枚举描述,转换失败则返回默认枚举描述
  2. public static string ToEnumDescOrDefaultByName<T>(this string name, string defaultValue) where T : struct, Enum
  3. {
  4.     //调用根据枚举名称转换成枚举描述方法
  5.     var result = name.ToEnumDescByName<T>();
  6.     if (!string.IsNullOrWhiteSpace(result))
  7.     {
  8.         return result;
  9.     }
  10.     //转换失败则返回默认枚举描述
  11.     return defaultValue;
  12. }
复制代码
做个简单单元测试,具体代码如下:
  1. [Fact]
  2. public void ToEnumDescOrDefaultByName()
  3. {
  4.     //正常枚举名称字符串,成功转换成枚举描述
  5.     var status = "Standby".ToEnumDescOrDefaultByName<StatusEnum>("测试");
  6.     Assert.Equal("待机", status);
  7.     //不存在的枚举名称字符串,返回指定默认枚举描述
  8.     var statusDefault = "StandbyNull".ToEnumDescOrDefaultByName<StatusEnum>("测试");
  9.     Assert.Equal("测试", statusDefault);
  10. }
复制代码
稍晚些时候我会把库上传至Nuget,大家可以直接使用Ideal.Core.Common。
:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Ideal

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4