上篇(.Net Standard擴展支持實例分享)介紹了OSS.Common的標準庫支持擴展,也列舉了可能遇到問題的解決方案。由於時間有限,同時.net standard暫時還沒有提供對DescriptionAttribute的支持,所以其中的轉化枚舉到字典列表的擴展當時按照第一種處理方式先行屏蔽, ...
上篇(.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):