0

I have to cast enum but I want this to be as generic as possbile. How can I replace the Cast<XX>() part with propertyType?

foreach (var prop in MainType.GetProperties().Where(x => x.PropertyType.IsEnum))
{
     var x = new { name = prop.Name, values = new List<object>() };

     foreach (var v in Enum.GetValues(prop.PropertyType).Cast<XX>())
         x.values.Add(new { p = v.GetAttribute<DescriptionAttribute>().Description, 
                            c = v.GetAttribute<DefaultValueAttribute>().Value });

     o.Add(x);
}


    public static TAttribute GetAttribute<TAttribute>(this Enum value) where TAttribute : Attribute
    {
        var type = value.GetType();
        var name = Enum.GetName(type, value);
        return type.GetField(name)
            .GetCustomAttributes(false)
            .OfType<TAttribute>()
            .SingleOrDefault();
    }

public enum JobApplicationState : short
{
    [Description("Active")]
    [DefaultValue(typeof(string), "bg-primary text-highlight")]
    Active = 1,
    [Description("Passive")]
    [DefaultValue(typeof(string), "bg-grey text-highlight")]
    Passive = 2,
    [Description("Rejected")]
    [DefaultValue(typeof(string), "bg-danger text-highlight")]
    Rejected = 3,
    [Description("Accepted")]
    [DefaultValue(typeof(string), "bg-success text-highlight")]
    Accepted = 4
}

THIS WORKED!

foreach (MemberInfo m in prop.PropertyType.GetFields())
{
    if (m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault() != null && m.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault() != null)
        {
             x.values.Add(
                 new
                 {
                     p = ((DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault()).Description,
                     c = ((DefaultValueAttribute)m.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault()).Value
        });
    } 
}
Mert
  • 6,432
  • 6
  • 32
  • 68

2 Answers2

2

You should realize that an enum is nothing more than a named wrapper around an integral value. I've described some details on how enums work here: Cast int to enum in C# .

The question here is to get attributes values from an enum. As you might imagine, this question is about getting attributes from the type, not about getting attributes from the value (there's no such thing). Still, if you call a method like void Foo<T>(T myEnum), the type T will hold all the necessary info, even though 'in real life' the value of myEnum is passed around as an integral type.

From this you can also deduce that you're actually looking for the attributes of the MemberInfo's of T, since you're looking for the members of the type (e.g. the enum). Again, all the details are in my post on how enums work. Hence the answer:

foreach (MemberInfo m in prop.PropertyType.GetFields())
{
    // use m.GetAttribute(...) 
}
Community
  • 1
  • 1
atlaste
  • 30,418
  • 3
  • 57
  • 87
1

Why don´t you simply cast to Enum:

foreach (var v in Enum.GetValues(prop.PropertyType).Cast<Enum>())

Now you can call your extension-method on every element within the returned list.

v.GetAttribute<MyType>()
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111