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

如何获取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();
    }
}

代码说明

  1. 先获取枚举的类型enumType;
  2. 遍历所有枚举值,对每个值:
    • 通过GetField(value.ToString())获取该枚举值对应的字段信息;
    • 调用GetCustomAttributes检查该字段是否带有ObsoleteAttribute;
    • 如果没有该特性,则保留这个枚举值;
  3. 最后将过滤后的结果转为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:50:37