如何从PermissionScope枚举属性获取对应字符串ID值?
问题描述
我定义了如下PermissionScope枚举,每个枚举项对应一个字符串ID:
public enum PermissionScope { OfflineAccess = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"; //ID 1 Profile = "14dad69e-099b-42c9-810b-d002981feec1"; //ID 2 }
我希望通过枚举属性名(如"offline_access"、"Profile")获取对应的字符串ID,比如遍历字符串数组时,能通过类似PermissionScope(scope)或FindByString方法,把对应ID赋值给ResourceAccess的Id属性,实现调用PermissionScope.OfflineAccess得到"7427e0e9-2fba-42fe-b0c0-848c9e6a8182"的效果。
解决方案
方法1:Enum.Parse+扩展方法
先统一字符串命名格式(比如把下划线命名转成枚举的帕斯卡命名),再解析枚举并取值:
public static class PermissionScopeExtensions { // 下划线命名转帕斯卡命名 private static string ToPascalCase(string input) { if (string.IsNullOrEmpty(input)) return input; return string.Join("", input.Split('_').Select(word => char.ToUpper(word[0]) + word.Substring(1).ToLower())); } // 通过名称获取对应ID public static string GetIdByName(string scopeName) { if (string.IsNullOrEmpty(scopeName)) throw new ArgumentNullException(nameof(scopeName)); var pascalCaseName = ToPascalCase(scopeName); if (Enum.TryParse<PermissionScope>(pascalCaseName, out var scope)) { return scope.ToString(); } throw new ArgumentException($"不存在名为{scopeName}的权限范围", nameof(scopeName)); } }
使用示例:
// 直接解析标准命名 var profileId = PermissionScopeExtensions.GetIdByName("Profile"); // 解析下划线格式命名 var offlineId = PermissionScopeExtensions.GetIdByName("offline_access"); // 遍历字符串数组场景 var scopeNames = new[] { "offline_access", "Profile" }; foreach(var name in scopeNames) { var resourceAccess = new ResourceAccess(); resourceAccess.Id = PermissionScopeExtensions.GetIdByName(name); }
方法2:预构建映射字典
如果需要频繁调用,提前构建名称到ID的映射字典,避免重复解析枚举:
public static class PermissionScopeHelper { private static readonly Dictionary<string, string> _nameToIdMap; static PermissionScopeHelper() { _nameToIdMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "OfflineAccess", PermissionScope.OfflineAccess.ToString() }, { "offline_access", PermissionScope.OfflineAccess.ToString() }, { "Profile", PermissionScope.Profile.ToString() } }; } public static string GetId(string scopeName) { if (_nameToIdMap.TryGetValue(scopeName, out var id)) { return id; } throw new ArgumentException($"无效的权限范围名称:{scopeName}", nameof(scopeName)); } }
使用示例:
var id = PermissionScopeHelper.GetId("offline_access");
方法3:自定义特性扩展枚举(更灵活)
如果后续需要给枚举项添加更多元数据,可以用特性标记,再通过反射读取:
首先定义特性类:
[AttributeUsage(AttributeTargets.Field)] public class PermissionIdAttribute : Attribute { public string Id { get; } public PermissionIdAttribute(string id) { Id = id; } }
修改枚举结构:
public enum PermissionScope { [PermissionId("7427e0e9-2fba-42fe-b0c0-848c9e6a8182")] OfflineAccess, [PermissionId("14dad69e-099b-42c9-810b-d002981feec1")] Profile }
编写扩展方法读取特性:
public static class PermissionScopeExtensions { // 直接从枚举项获取ID public static string GetId(this PermissionScope scope) { var field = scope.GetType().GetField(scope.ToString()); var attribute = field.GetCustomAttribute<PermissionIdAttribute>(); return attribute?.Id ?? throw new InvalidOperationException($"枚举项{scope}未配置ID"); } // 通过名称获取ID public static string GetIdByName(string scopeName) { if (Enum.TryParse<PermissionScope>(ToPascalCase(scopeName), out var scope)) { return scope.GetId(); } throw new ArgumentException($"不存在名为{scopeName}的权限范围", nameof(scopeName)); } private static string ToPascalCase(string input) { if (string.IsNullOrEmpty(input)) return input; return string.Join("", input.Split('_').Select(word => char.ToUpper(word[0]) + word.Substring(1).ToLower())); } }
使用示例:
// 直接通过枚举项取ID var offlineId = PermissionScope.OfflineAccess.GetId(); // 通过名称取ID var profileId = PermissionScopeExtensions.GetIdByName("offline_access");
内容的提问来源于stack exchange,提问作者Bac Babc
相关产品推荐
相关产品推荐

