You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:37:03