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

C#枚举成员共享整数值时,如何获取原始唯一Enum对象?

C#中处理值重复的枚举成员:保留每个成员的元数据信息

在C#中,枚举是值类型,相同整数值的枚举成员在运行时会被视为同一个实例,所以不管用Enum.GetValues()、Enum.Parse()还是反射FieldInfo.GetValue(),返回的都是同一个Enum对象,无法直接区分像Value1和Value4这样数值相同的成员。但我们可以通过保留枚举成员的元数据(字段名称、自定义属性)来满足需求——因为真正需要区分的是这些元数据,而非Enum对象本身。

解决方案:封装枚举成员的完整元数据

核心思路是通过反射枚举类型的所有静态字段,为每个字段单独提取元数据信息,并和对应的枚举值绑定。我们可以自定义一个类来封装这些信息,方便后续使用。

1. 定义元数据封装类

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

public class EnumMemberInfo<TEnum> where TEnum : Enum
{
    // 枚举值(数值相同的成员会共享同一个实例)
    public TEnum Value { get; set; }
    // 枚举成员的原始名称
    public string Name { get; set; }
    // Description属性的内容
    public string Description { get; set; }
    // Display.Name属性的内容
    public string DisplayName { get; set; }
}

2. 编写获取所有枚举成员信息的方法

using System.Reflection;

public static class EnumHelper
{
    public static List<EnumMemberInfo<TEnum>> GetAllEnumMembers<TEnum>() where TEnum : Enum
    {
        var enumType = typeof(TEnum);
        var members = new List<EnumMemberInfo<TEnum>>();

        // 获取枚举类型的所有公共静态字段(即枚举成员)
        var fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
        foreach (var field in fields)
        {
            // 跳过编译器自动生成的非枚举成员字段
            if (!field.FieldType.IsEnum)
                continue;

            // 获取枚举值
            var enumValue = (TEnum)field.GetValue(null);
            
            // 提取Description属性
            var descriptionAttr = field.GetCustomAttribute<DescriptionAttribute>();
            var description = descriptionAttr?.Description ?? field.Name;
            
            // 提取Display属性
            var displayAttr = field.GetCustomAttribute<DisplayAttribute>();
            var displayName = displayAttr?.Name ?? field.Name;

            members.Add(new EnumMemberInfo<TEnum>
            {
                Value = enumValue,
                Name = field.Name,
                Description = description,
                DisplayName = displayName
            });
        }

        return members;
    }
}

3. 使用示例

// 获取Testing枚举的所有成员信息
var allMembers = EnumHelper.GetAllEnumMembers<Testing>();

foreach (var member in allMembers)
{
    Console.WriteLine($"成员名称: {member.Name}, 枚举值: {(int)member.Value}");
    Console.WriteLine($"显示名称: {member.DisplayName}, 描述: {member.Description}");
    Console.WriteLine("---");
}

输出结果会完整保留每个成员的独特信息:

成员名称: Value1, 枚举值: 0
显示名称: Value 1, 描述: This is Value1
---
成员名称: Value2, 枚举值: 1
显示名称: Value 2, 描述: This is Value2
---
成员名称: Value3, 枚举值: 2
显示名称: Value 3, 描述: This is Value3
---
成员名称: Value4, 枚举值: 0
显示名称: Value 4, 描述: This is Value4
---

补充说明

  • 虽然Value1和Value4对应的Value属性是同一个Enum实例,但我们通过封装的Name、Description、DisplayName保留了每个成员的独特元数据,完全满足下拉列表展示、工具提示等业务场景需求。
  • 如果确实需要直接关联字段信息,可以在EnumMemberInfo中额外添加FieldInfo属性,但大多数场景下,封装后的元数据已经足够使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:37:38