当我将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);
但坚持下一步。
答案 0 :(得分:5)
我正在获得ValueA,但期望获得ValueB。
你得到整数1所代表的值。你看到那个ValueA
的事实与Parse
无关,而且一切都是做ToString
。
记住,当你有一个枚举类型的值时,它真的非常重要,它实际上只是一个整数。对于相同的整数值,可以有多个名称,当您获得该值时,它们完全无法区分。
听起来像你真正想做的事情 - 可能除了你的解析方法之外 - 就是写一个ToStringWithoutObsolete
方法。这可以将值映射到名称,但仅适用于没有过时属性的值。请注意,在代码中的任何位置使用typeof(T).GetField(a.ToString())
都会导致结果无法预测。最好在枚举类型中获取 all 静态字段。例如:
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);