检查枚举是否已过时
Check if enum is obsolete
如何检查 enum
是否标记为过时?
public enum MyEnums
{
MyEnum1,
[Obsolete("How can you know that I'm obsolete?")]
MyEnum2,
MyEnum3
}
现在在运行时,我需要知道哪些已过时:
foreach (var myEnum in Enum.GetValues(typeof(MyEnums)).Cast<MyEnums>())
{
// How can I check if myEnum is obsolete?
}
以下方法检查枚举值是否具有 Obsolete
属性:
public static bool IsObsolete(Enum value)
{
var fi = value.GetType().GetField(value.ToString());
var attributes = (ObsoleteAttribute[])
fi.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
你可以这样使用它:
var isObsolete2 = IsObsolete(MyEnums.MyEnum2); // returns true
var isObsolete3 = IsObsolete(MyEnums.MyEnum3); // returns false
可以,但需要使用 反射:
bool hasIt = typeof (MyEnums).GetField("MyEnum2")
.GetCustomAttribute(typeof (ObsoleteAttribute)) != null;
另一方面,您可以使用一些 LINQ 获取所有过时的枚举字段:
IEnumerable<FieldInfo> obsoleteEnumValueFields = typeof (MyEnums)
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(fieldInfo => fieldInfo.GetCustomAttribute(typeof (ObsoleteAttribute)) != null);
最后,使用上面的结果,你可以得到所有过时的枚举值!
IEnumerable<MyEnums> obsoleteEnumValues = obsoleteEnumValueFields
.Select(fieldInfo => (MyEnums)fieldInfo.GetValue(null));
谢谢@M4N 这是您的解决方案的扩展方法:
public static bool IsObsolete(this Enum value)
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
ObsoleteAttribute[] attributes = (ObsoleteAttribute[])fieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
这样称呼它:
bool isObsolete2 = MyEnums.MyEnum2.IsObsolete(); // true
bool isObsolete3 = MyEnums.MyEnum3.IsObsolete(); // false
这是一个非常干净的扩展方法。诀窍是您正在使用枚举名称反映枚举类型之外的字段。
public static bool IsObsolete(this Enum value)
{
var enumType = value.GetType();
var enumName = enumType.GetEnumName(value);
var fieldInfo = enumType.GetField(enumName);
return Attribute.IsDefined(fieldInfo, typeof(ObsoleteAttribute));
}
我刚刚制作了这个实用程序 class 来处理这个问题:
public static class EnumUtils
{
public static bool IsObsolete<TEnumType>(TEnumType value) where TEnumType : struct
{
var fi = value.GetType().GetField(value.ToString());
var attributes = (ObsoleteAttribute[])
fi.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
public static List<TEnumType> GetObsoleteValues<TEnumType>() where TEnumType : struct
{
return GetAllValues<TEnumType>().Where(e => IsObsolete(e)).ToList();
}
public static List<TEnumType> GetNonObsoleteValues<TEnumType>() where TEnumType : struct
{
return GetAllValues<TEnumType>().Where(e => !IsObsolete(e)).ToList();
}
public static List<TEnumType> GetAllValues<TEnumType>() where TEnumType : struct
{
return Enum.GetValues(typeof(TEnumType)).Cast<TEnumType>().ToList();
}
}
以及对应的单元测试(MSTest):
[TestClass]
public class EnumUtilsTest : UnitTestBase
{
#pragma warning disable CS0612 // Type or member is obsolete
[TestMethod]
public void GetAllValues_Test()
{
var values = EnumUtils.GetAllValues<UnitTestEnumValues>();
Assert.AreEqual(4, values.Count);
Assert.AreEqual(UnitTestEnumValues.A, values[0]);
Assert.AreEqual(UnitTestEnumValues.B_Obsolete, values[1]);
Assert.AreEqual(UnitTestEnumValues.C, values[2]);
Assert.AreEqual(UnitTestEnumValues.D_Obsolete, values[3]);
}
[TestMethod]
public void GetObsoleteValues_Test()
{
var values = EnumUtils.GetObsoleteValues<UnitTestEnumValues>();
Assert.AreEqual(2, values.Count);
Assert.AreEqual(UnitTestEnumValues.B_Obsolete, values[0]);
Assert.AreEqual(UnitTestEnumValues.D_Obsolete, values[1]);
}
[TestMethod]
public void GetNonObsoleteValues_Test()
{
var values = EnumUtils.GetNonObsoleteValues<UnitTestEnumValues>();
Assert.AreEqual(2, values.Count);
Assert.AreEqual(UnitTestEnumValues.A, values[0]);
Assert.AreEqual(UnitTestEnumValues.C, values[1]);
}
[TestMethod]
public void IsObsolete_Test()
{
Assert.AreEqual(false, EnumUtils.IsObsolete(UnitTestEnumValues.A));
Assert.AreEqual(true, EnumUtils.IsObsolete(UnitTestEnumValues.B_Obsolete));
Assert.AreEqual(false, EnumUtils.IsObsolete(UnitTestEnumValues.C));
Assert.AreEqual(true, EnumUtils.IsObsolete(UnitTestEnumValues.D_Obsolete));
}
public enum UnitTestEnumValues
{
A,
[Obsolete]
B_Obsolete,
C,
[Obsolete]
D_Obsolete
}
#pragma warning restore CS0612 // Type or member is obsolete
}
如何检查 enum
是否标记为过时?
public enum MyEnums
{
MyEnum1,
[Obsolete("How can you know that I'm obsolete?")]
MyEnum2,
MyEnum3
}
现在在运行时,我需要知道哪些已过时:
foreach (var myEnum in Enum.GetValues(typeof(MyEnums)).Cast<MyEnums>())
{
// How can I check if myEnum is obsolete?
}
以下方法检查枚举值是否具有 Obsolete
属性:
public static bool IsObsolete(Enum value)
{
var fi = value.GetType().GetField(value.ToString());
var attributes = (ObsoleteAttribute[])
fi.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
你可以这样使用它:
var isObsolete2 = IsObsolete(MyEnums.MyEnum2); // returns true
var isObsolete3 = IsObsolete(MyEnums.MyEnum3); // returns false
可以,但需要使用 反射:
bool hasIt = typeof (MyEnums).GetField("MyEnum2")
.GetCustomAttribute(typeof (ObsoleteAttribute)) != null;
另一方面,您可以使用一些 LINQ 获取所有过时的枚举字段:
IEnumerable<FieldInfo> obsoleteEnumValueFields = typeof (MyEnums)
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(fieldInfo => fieldInfo.GetCustomAttribute(typeof (ObsoleteAttribute)) != null);
最后,使用上面的结果,你可以得到所有过时的枚举值!
IEnumerable<MyEnums> obsoleteEnumValues = obsoleteEnumValueFields
.Select(fieldInfo => (MyEnums)fieldInfo.GetValue(null));
谢谢@M4N 这是您的解决方案的扩展方法:
public static bool IsObsolete(this Enum value)
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
ObsoleteAttribute[] attributes = (ObsoleteAttribute[])fieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
这样称呼它:
bool isObsolete2 = MyEnums.MyEnum2.IsObsolete(); // true
bool isObsolete3 = MyEnums.MyEnum3.IsObsolete(); // false
这是一个非常干净的扩展方法。诀窍是您正在使用枚举名称反映枚举类型之外的字段。
public static bool IsObsolete(this Enum value)
{
var enumType = value.GetType();
var enumName = enumType.GetEnumName(value);
var fieldInfo = enumType.GetField(enumName);
return Attribute.IsDefined(fieldInfo, typeof(ObsoleteAttribute));
}
我刚刚制作了这个实用程序 class 来处理这个问题:
public static class EnumUtils
{
public static bool IsObsolete<TEnumType>(TEnumType value) where TEnumType : struct
{
var fi = value.GetType().GetField(value.ToString());
var attributes = (ObsoleteAttribute[])
fi.GetCustomAttributes(typeof(ObsoleteAttribute), false);
return (attributes != null && attributes.Length > 0);
}
public static List<TEnumType> GetObsoleteValues<TEnumType>() where TEnumType : struct
{
return GetAllValues<TEnumType>().Where(e => IsObsolete(e)).ToList();
}
public static List<TEnumType> GetNonObsoleteValues<TEnumType>() where TEnumType : struct
{
return GetAllValues<TEnumType>().Where(e => !IsObsolete(e)).ToList();
}
public static List<TEnumType> GetAllValues<TEnumType>() where TEnumType : struct
{
return Enum.GetValues(typeof(TEnumType)).Cast<TEnumType>().ToList();
}
}
以及对应的单元测试(MSTest):
[TestClass]
public class EnumUtilsTest : UnitTestBase
{
#pragma warning disable CS0612 // Type or member is obsolete
[TestMethod]
public void GetAllValues_Test()
{
var values = EnumUtils.GetAllValues<UnitTestEnumValues>();
Assert.AreEqual(4, values.Count);
Assert.AreEqual(UnitTestEnumValues.A, values[0]);
Assert.AreEqual(UnitTestEnumValues.B_Obsolete, values[1]);
Assert.AreEqual(UnitTestEnumValues.C, values[2]);
Assert.AreEqual(UnitTestEnumValues.D_Obsolete, values[3]);
}
[TestMethod]
public void GetObsoleteValues_Test()
{
var values = EnumUtils.GetObsoleteValues<UnitTestEnumValues>();
Assert.AreEqual(2, values.Count);
Assert.AreEqual(UnitTestEnumValues.B_Obsolete, values[0]);
Assert.AreEqual(UnitTestEnumValues.D_Obsolete, values[1]);
}
[TestMethod]
public void GetNonObsoleteValues_Test()
{
var values = EnumUtils.GetNonObsoleteValues<UnitTestEnumValues>();
Assert.AreEqual(2, values.Count);
Assert.AreEqual(UnitTestEnumValues.A, values[0]);
Assert.AreEqual(UnitTestEnumValues.C, values[1]);
}
[TestMethod]
public void IsObsolete_Test()
{
Assert.AreEqual(false, EnumUtils.IsObsolete(UnitTestEnumValues.A));
Assert.AreEqual(true, EnumUtils.IsObsolete(UnitTestEnumValues.B_Obsolete));
Assert.AreEqual(false, EnumUtils.IsObsolete(UnitTestEnumValues.C));
Assert.AreEqual(true, EnumUtils.IsObsolete(UnitTestEnumValues.D_Obsolete));
}
public enum UnitTestEnumValues
{
A,
[Obsolete]
B_Obsolete,
C,
[Obsolete]
D_Obsolete
}
#pragma warning restore CS0612 // Type or member is obsolete
}