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
相关产品推荐
相关产品推荐

