上篇(.Net Standard扩展支持实例分享)介绍了OSS.Common的标准库支持扩展,也列举了可能遇到问题的解决方案。由于时间有限,同时.net standard暂时还没有提供对DescriptionAttribute的支持,所以其中的转化枚举到字典列表的扩展当时按照第一种处理方式先行屏蔽,这次按照第三种方式完善一下。
既然.net standard 下没有提供对DescriptAttribute的支持,首先我先自定义一个Attribute来补充:
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)] public class OSDescriptAttribute : Attribute { public OSDescriptAttribute(string description) { this.Description = description; } public string Description { get; set; } }
其次定义一个线程安全的字典,来全局缓存枚举对应的枚举字典列表,减少下次获取的代码执行:
private static ConcurrentDictionary<string, Dictionary<string, string>> enumDirs =new ConcurrentDictionary<string, Dictionary<string, string>>();
最后我们来实现获取字典部分的具体操作:
public static Dictionary<string, string> ToEnumDirs(this Type enType, bool isIntValue = true) { #if NETFW if (!enType.IsEnum) #else if (!enType.GetTypeInfo().IsEnum) #endif throw new ArgumentException("获取枚举字典,参数必须是枚举类型!"); string key = string.Concat(enType.FullName, isIntValue); Dictionary<string, string> dirs; enumDirs.TryGetValue(key, out dirs); if (dirs != null) return dirs.Copy(); dirs = new Dictionary<string, string>(); var values = Enum.GetValues(enType); foreach (var value in values) { var name = Enum.GetName(enType, value); string resultValue = isIntValue ? ((int) value).ToString() : value.ToString(); #if NETFW var attr = enType.GetField(name)?.GetCustomAttribute<OSDescriptAttribute>(); #else var attr = enType.GetTypeInfo().GetDeclaredField(name)?.GetCustomAttribute<OSDescriptAttribute>(); #endif dirs.Add(resultValue, attr == null ? name : attr.Description); } enumDirs.TryAdd(key, dirs); return dirs.Copy(); }
以后我们就可以在所有的业务的代码中进行 typeof(枚举类型).ToEnumDirs() 的方法来获取枚举对应的字典列表,例如:
typeof (ResultTypes).ToEnumDirs();
代码详见:github
如果你对OSS开源系列有兴趣,欢饮关注公号(osscoder):