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

如何在C#中通过Display属性值获取对应的枚举成员?

Convert Display Attribute String to Corresponding Enum Member in C#

Got it, let's tackle this problem: you have an enum decorated with Display attributes, and your external API returns the Name value from those attributes (like "CHANNEL_CHANNEL"), but you need to map that string back to the actual GTMType enum member. Here are a couple of robust approaches to handle this.

1. Basic Reflection-Based Method

First, we can create a generic helper method that uses reflection to scan the enum's fields and match the Display attribute's Name to the input string.

using System.ComponentModel;
using System.Reflection;

public static class EnumExtensions
{
    public static TEnum GetEnumFromDisplayName<TEnum>(string displayName) where TEnum : Enum
    {
        // Iterate over all public static fields in the enum type
        foreach (FieldInfo field in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static))
        {
            // Check if the field has a Display attribute
            if (Attribute.GetCustomAttribute(field, typeof(DisplayAttribute)) is DisplayAttribute displayAttr)
            {
                if (displayAttr.Name.Equals(displayName, StringComparison.OrdinalIgnoreCase))
                {
                    return (TEnum)field.GetValue(null);
                }
            }
            // Optional: Fall back to matching the enum member name directly (in case of edge cases)
            else if (field.Name.Equals(displayName, StringComparison.OrdinalIgnoreCase))
            {
                return (TEnum)field.GetValue(null);
            }
        }

        // Throw an exception if no match is found (you can also return default(TEnum) if preferred)
        throw new ArgumentException(
            $"No {typeof(TEnum).Name} member found with display name '{displayName}'",
            nameof(displayName));
    }
}

How to Use It

Update your GetDataForAccountByID method to call this helper:

public Account GetDataForAccountByID(string id) 
{ 
    AccountModel accountModel = GetDataFromAnotherSystem(id); 

    var account = new Account 
    { 
        EmailAddress = accountModel.Email, 
        GTMType = EnumExtensions.GetEnumFromDisplayName<GTMType>(accountModel.GTMType)
    }; 

    return account; // Don't forget to return the constructed Account!
}

2. Cached Version for Better Performance

If you're going to use this conversion frequently, reflection can add overhead. To optimize, we can cache the mapping between Display names and enum members once when the helper class is first accessed.

using System.ComponentModel;
using System.Reflection;
using System.Collections.Generic;

public static class EnumDisplayNameCache<TEnum> where TEnum : struct, Enum
{
    // Cache the display name -> enum member mapping
    private static readonly Dictionary<string, TEnum> _displayNameToEnumMap = new(StringComparer.OrdinalIgnoreCase);

    static EnumDisplayNameCache()
    {
        foreach (FieldInfo field in typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static))
        {
            // Add Display attribute name to the cache
            if (Attribute.GetCustomAttribute(field, typeof(DisplayAttribute)) is DisplayAttribute displayAttr 
                && !string.IsNullOrWhiteSpace(displayAttr.Name))
            {
                _displayNameToEnumMap[displayAttr.Name] = (TEnum)field.GetValue(null);
            }
            // Add enum member name as a fallback
            _displayNameToEnumMap[field.Name] = (TEnum)field.GetValue(null);
        }
    }

    public static TEnum GetEnumFromDisplayName(string displayName)
    {
        if (_displayNameToEnumMap.TryGetValue(displayName, out TEnum enumValue))
        {
            return enumValue;
        }

        throw new ArgumentException(
            $"No {typeof(TEnum).Name} member found with display name '{displayName}'",
            nameof(displayName));
    }

    // Optional: Add a try-get method to handle invalid values gracefully
    public static bool TryGetEnumFromDisplayName(string displayName, out TEnum enumValue)
    {
        return _displayNameToEnumMap.TryGetValue(displayName, out enumValue);
    }
}

Usage with Cache

public Account GetDataForAccountByID(string id) 
{ 
    AccountModel accountModel = GetDataFromAnotherSystem(id); 

    // Use the cached helper
    if (!EnumDisplayNameCache<GTMType>.TryGetEnumFromDisplayName(accountModel.GTMType, out GTMType gtmType))
    {
        // Handle invalid GTMType value here (e.g., throw custom exception, set default)
        throw new InvalidOperationException($"Invalid GTMType value received: {accountModel.GTMType}");
    }

    var account = new Account 
    { 
        EmailAddress = accountModel.Email, 
        GTMType = gtmType
    }; 

    return account;
}

Key Notes

  • Make sure to include the System.ComponentModel and System.Reflection namespaces in your code file.
  • The StringComparison.OrdinalIgnoreCase makes the matching case-insensitive (adjust this if you need exact case matching).
  • The try-get method is useful if you expect the API might return invalid values and want to handle them without throwing exceptions immediately.

内容的提问来源于stack exchange,提问作者ankur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:58:42