检查枚举是否已过时

时间:2015-04-23 19:22:21

标签: c# enums

如何检查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?
}

5 个答案:

答案 0 :(得分:13)

以下方法检查枚举值是否具有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

答案 1 :(得分:2)

您可以,但您需要使用反射

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));

答案 2 :(得分:2)

这是一个非常干净的扩展方法。诀窍在于你使用枚举的名称来反映枚举类型的字段。

   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));
   }

答案 3 :(得分:0)

感谢@ M4N,这是解决方案的扩展方法方法:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import IPython.display as ipyd
from libs import vgg16 # Download here! https://github.com/pkmital/CADL/tree/master/session-4/libs

pandaimage = plt.imread('panda.jpg')
pandaimage = vgg16.preprocess(pandaimage)
plt.imshow(pandaimage)

img_4d = np.array([pandaimage])

g = tf.get_default_graph()
input_placeholder = tf.Variable(img_4d,trainable=False)
to_add_image = tf.Variable(tf.random_normal([224,224,3], mean=0.0, stddev=0.1, dtype=tf.float32))
combined_images_not_clamped = input_placeholder+to_add_image

filledmax = tf.fill(tf.shape(combined_images_not_clamped), 1.0)
filledmin = tf.fill(tf.shape(combined_images_not_clamped), 0.0)
greater_than_one = tf.greater(combined_images_not_clamped, filledmax)

combined_images_with_max = tf.where(greater_than_one, filledmax, combined_images_not_clamped)
lower_than_zero =tf.less(combined_images_with_max, filledmin)
combined_images = tf.where(lower_than_zero, filledmin, combined_images_with_max)

net = vgg16.get_vgg_model()
tf.import_graph_def(net['graph_def'], name='vgg')
names = [op.name for op in g.get_operations()]

style_layer = 'prob:0'
the_prediction = tf.import_graph_def(
    net['graph_def'],
    name='vgg',
    input_map={'images:0': combined_images},return_elements=[style_layer])

goldfish_expected_np = np.zeros(1000)
goldfish_expected_np[1]=1.0
goldfish_expected_tf = tf.Variable(goldfish_expected_np,dtype=tf.float32,trainable=False)
loss = tf.reduce_sum(tf.square(the_prediction[0]-goldfish_expected_tf))
optimizer = tf.train.AdamOptimizer().minimize(loss)


sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())


def show_many_images(*images):
    fig = plt.figure()
    for i in range(len(images)):
        print(images[i].shape)
        subplot_number = 100+10*len(images)+(i+1)
        plt.subplot(subplot_number)
        plt.imshow(images[i])
    plt.show()



for i in range(1000):
    _, loss_val = sess.run([optimizer,loss])

    if i%100==1:
        print("Loss at iteration %d: %f" % (i,loss_val))
        _, loss_val,adversarial_image,pred,nematode = sess.run([optimizer,loss,combined_images,the_prediction,to_add_image])
        res = np.squeeze(pred)
        average = np.mean(res, 0)
        res = res / np.sum(average)
        plt.imshow(adversarial_image[0])
        plt.show()
        print([(res[idx], net['labels'][idx]) for idx in res.argsort()[-5:][::-1]])
        show_many_images(img_4d[0],nematode,adversarial_image[0])
        plt.imsave('adversarial_goldfish.pdf',adversarial_image[0],format='pdf') # save for printing

这样称呼:

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);
}

答案 4 :(得分:0)

我刚刚制作了这个utils类来处理此问题:

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
    }