c# - 解析枚举跳过已过时

标签 c# generics enums

当我将 int 值转换为枚举时如何跳过过时的值?我在下面有最小的工作示例:

using System;

public class Program
{
    public static void Main()
    {
        int valueInt = 1;
        var en = (TestObsolete)valueInt;
        Console.WriteLine(en);
    }
}

enum TestObsolete
{
    Undefined,
    [Obsolete]
    ValueA = 1,
    ValueB=1,
}

我得到的是 ValueA,但期望得到的是 ValueB。特别是我对具有以下签名的通用方法感兴趣:

public static T ParseEnumWithoutObsolete<T>(int val) where T: struct {

我试着做这样的事情:

T @enum;
var enumValues = Enum.GetValues(typeof(T)).Cast<T>();
var obsoleteValues = enumValues.Where(a => typeof(T).GetField(a.ToString()).CustomAttributes.Any(t => t is ObsoleteAttribute));
var activeValues = enumValues.Except(obsoleteValues);

但卡在了下一步。

最佳答案

I'm getting ValueA, but expecting to get ValueB.

您将获得由整数 1 表示的值。您看到的事实是 ValueAParse无关, 以及与 ToString 有关的一切.

请记住,当您拥有枚举类型的值时,它实际上只是一个整数,这一点非常非常重要。同一个整数值可以有多个名称,当您刚刚获得该值时,它们完全无法区分。

在我看来,您真正想做的事情——可能除了您的解析方法之外——是写一个 ToStringWithoutObsolete方法。这可以将值映射到名称,但仅限于没有过时属性的值。请注意,使用 typeof(T).GetField(a.ToString())代码中的任何地方都会使结果不可预测。最好获取枚举类型中的所有静态字段。例如:

var valueToName = typeof(T)
    .GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
    .Where(f => !f.IsDefined(typeof(ObsoleteAttribute), false))
    .ToDictionary(f => (T) f.GetValue(null),
                  f => f.Name);

关于c# - 解析枚举跳过已过时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42758793/

相关文章:

c# - 在编辑事件时,如何检查是否在下拉列表单元格中选择了一个值

c# - 如何获取组合框的内容并将它们添加到数组中?

jsp - 在JSP中将枚举值作为标记属性传递

java - 具体类作为通用参数

generics - 为什么 `From` 不自动用于强制实现 trait 类型

c# - 如何使用 Datastax C# 驱动程序将 C# 枚举映射到 Cassandra 字段?

c++ - 声明指向二维枚举数组的指针

c# - Byte Vigenere Cipher,解密错误

c# - 根据类型选择数据模板

java - 将泛型类型乘以二 - 二叉树方法