4

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.

3 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The code in your "Demo" link works but the code in the snippet does not. I had an error with "nameof" method. The assingment to the variable res works in the demo code with this line: var res = typeof(Books).GetField("IndianInTheCupboard").GetCustomAttribute<BookDetails>(false).Author;
Woops, I copied the wrong line. I meant the one in your post, not the demo. var res = typeof(Books) .GetField(nameof(Books.IndianInTheCupboard)) .GetCustomAttribute<BookDetails>(false) .Author;
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;
    }
}

1 Comment

Love the extension method.
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;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.