如何获取C#枚举中未标记Obsolete的非过时值列表?
问题描述
我有一个包含过时值的枚举MyEnum,其中Item2被标记了[Obsolete]特性。目前我能获取该枚举的所有值列表,但没法识别并排除过时值。现有扩展方法GetList可以返回所有枚举值,希望修改这个方法,让它只返回未标记Obsolete的枚举值,求可行的修改方案。
示例枚举代码:
public enum MyEnum { Item1 = 1, [Obsolete] Item2 = 2, Item3 = 3 }
现有扩展方法代码:
public static class MyEnumExt { /// <summary> /// 我想修改这个方法,只返回未过时的枚举值 /// </summary> public static List<MyEnum> GetList(this MyEnum t) { return Enum.GetValues(t.GetType()).Cast<MyEnum>().ToList(); } }
解决方案
可以通过反射检查每个枚举值对应的字段是否带有ObsoleteAttribute,以此过滤掉过时的枚举项。修改后的扩展方法如下:
using System.Reflection; public static class MyEnumExt { /// <summary> /// 返回未标记Obsolete的枚举值列表 /// </summary> public static List<MyEnum> GetList(this MyEnum t) { var enumType = t.GetType(); return Enum.GetValues(enumType) .Cast<MyEnum>() .Where(value => !enumType.GetField(value.ToString()) .GetCustomAttributes(typeof(ObsoleteAttribute), inherit: false) .Any()) .ToList(); } }
代码说明
- 先获取枚举的类型
enumType; - 遍历所有枚举值,对每个值:
- 通过
GetField(value.ToString())获取该枚举值对应的字段信息; - 调用
GetCustomAttributes检查该字段是否带有ObsoleteAttribute; - 如果没有该特性,则保留这个枚举值;
- 通过
- 最后将过滤后的结果转为
List<MyEnum>返回。
可选优化:缓存结果
如果这个方法会被频繁调用,可以加入缓存逻辑,避免每次反射带来的性能损耗:
using System.Reflection; using System.Collections.Concurrent; public static class MyEnumExt { private static readonly ConcurrentDictionary<Type, List<MyEnum>> _cachedEnumValues = new(); /// <summary> /// 返回未标记Obsolete的枚举值列表 /// </summary> public static List<MyEnum> GetList(this MyEnum t) { var enumType = t.GetType(); return _cachedEnumValues.GetOrAdd(enumType, type => Enum.GetValues(type) .Cast<MyEnum>() .Where(value => !type.GetField(value.ToString()) .GetCustomAttributes(typeof(ObsoleteAttribute), inherit: false) .Any()) .ToList()); } }
第一次调用后,过滤结果会被缓存到字典中,后续调用直接读取缓存即可。
内容的提问来源于stack exchange,提问作者Shewan
相关产品推荐
相关产品推荐

