当我将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,
}
Run Code Online (Sandbox Code Playgroud)
我正在获得ValueA,但期望获得ValueB.特别是我对以下签名的泛型方法感兴趣:
public static T ParseEnumWithoutObsolete<T>(int val) where T: struct {
Run Code Online (Sandbox Code Playgroud)
我试着这样做:
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);
Run Code Online (Sandbox Code Playgroud)
但坚持下一步.
我正在获得ValueA,但期望获得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);
Run Code Online (Sandbox Code Playgroud)