1

My project has this BookDetails attribute:

public enum Books
{
    [BookDetails("Jack London", 1906)]
    WhiteFange,

    [BookDetails("Herman Melville", 1851)]
    MobyDick,

    [BookDetails("Lynne Reid Banks", 1980)]
    IndianInTheCupboard

}

and code for attribute here:

[AttributeUsage(AttributeTargets.Field)]
public class BookDetails : Attribute
{
    public string Author { get; }
    public int YearPublished { get; }

    public BookDetails(string author, int yearPublished)
    {
        Author = author;
        YearPublished = yearPublished;
    }
}

How do I get the author for a given Book?

Tried this messy code but it didn't work:

 var author = Books.IndianInTheCupboard.GetType().GetCustomAttributes(false).GetType().GetProperty("Author");  // returns null

Thanks, there's got to be a better way than what I was trying above.

H.B.
  • 142,212
  • 27
  • 297
  • 366
RayLoveless
  • 17,894
  • 21
  • 72
  • 91

3 Answers3

3

Since the attribute is attached to an enum field, you should apply GetCustomAttribute to FieldInfo:

var res = typeof(Books)
    .GetField(nameof(Books.IndianInTheCupboard))
    .GetCustomAttribute<BookDetails>(false)
    .Author;

Since attribute type is known statically, applying generic version of the GetCustomAttribute<T> method yields better type safety for getting the Author attribute.

Demo.

Sergey Kalinichenko
  • 697,062
  • 78
  • 1,055
  • 1,465
1

Your solution does not work because you are trying to find attribute of the type Books, but not attribute of the enumeration element. It works.

var fieldInfo = typeof(Books).GetField(Books.IndianInTheCupboard.ToString());
var attribute = fieldInfo.GetCustomAttributes(typeof(BookDetails), false).FirstOrDefault() as BookDetails;
var author = attribute.Author;

If you need to get values of this attribute often you can write extension for it.

public static class EnumExtensions
{
    public static BookDetails GetDescription(this Books value)
    {
        var fieldInfo = value.GetType().GetField(value.ToString());
        var attribute = fieldInfo.GetCustomAttributes(typeof(BookDetails), false).FirstOrDefault() as BookDetails;

        return attribute;
    }
}
Valerii
  • 2,029
  • 2
  • 11
  • 25
0

Already by answered Bryan Rowe. Replication of his solution accord your example:

    var type = typeof(Books);
    var memInfo = type.GetMember(Books.IndianInTheCupboard.ToString());
    var attributes = memInfo[0].GetCustomAttributes(typeof(BookDetails), false);
    var description = ((BookDetails)attributes[0]).Author;
4D1C70
  • 480
  • 3
  • 10