当我将 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 表示的值。您看到的事实是 ValueA
与Parse
无关, 以及与 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/