4

Is there a way for me to access a C# class attribute?

For instance, if I have the following class:

...
[TableName("my_table_name")]
public class MyClass
{
    ...
}

Can I do something like:

MyClass.Attribute.TableName => my_table_name

Thanks!

ovatsug25
  • 7,786
  • 7
  • 34
  • 48

3 Answers3

5

You can use reflection to get it. Here's is a complete encompassing example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    public class TableNameAttribute : Attribute
    {
        public TableNameAttribute(string tableName)
        {
            this.TableName = tableName;
        }
        public string TableName { get; set; }
    }

    [TableName("my_table_name")]
    public class SomePoco
    {
        public string FirstName { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var classInstance = new SomePoco() { FirstName = "Bob" };
            var tableNameAttribute = classInstance.GetType().GetCustomAttributes(true).Where(a => a.GetType() == typeof(TableNameAttribute)).Select(a =>
            {
                return a as TableNameAttribute;
            }).FirstOrDefault();

            Console.WriteLine(tableNameAttribute != null ? tableNameAttribute.TableName : "null");
            Console.ReadKey(true);
        }
    }    
}
Ryan Mann
  • 5,178
  • 32
  • 42
5

You can use Attribute.GetCustomAttribute method for that:

var tableNameAttribute = (TableNameAttribute)Attribute.GetCustomAttribute(
    typeof(MyClass), typeof(TableNameAttribute), true);

However this is too verbose for my taste, and you can really make your life much easier by the following little extension method:

public static class AttributeUtils
{
    public static TAttribute GetAttribute<TAttribute>(this Type type, bool inherit = true) where TAttribute : Attribute
    {
        return (TAttribute)Attribute.GetCustomAttribute(type, typeof(TAttribute), inherit);
    }
}

so you can use simply

var tableNameAttribute = typeof(MyClass).GetAttribute<TableNameAttribute>();
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
2

Here's an extension that will make it easier, by extending object to give you an attribute helper.

namespace System
{
    public static class ReflectionExtensions
    {
        public static T GetAttribute<T>(this object classInstance) where T : class
        {
            return ReflectionExtensions.GetAttribute<T>(classInstance, true);
        }
        public static T GetAttribute<T>(this object classInstance, bool includeInheritedAttributes) where T : class
        {
            if (classInstance == null)
                return null;

            Type t = classInstance.GetType();
            object attr = t.GetCustomAttributes(includeInheritedAttributes).Where(a => a.GetType() == typeof(T)).FirstOrDefault();
            return attr as T;
        }
    }
}

This would turn my previous answer into:

class Program
{
    static void Main(string[] args)
    {
        var classInstance = new SomePoco() { FirstName = "Bob" };
        var tableNameAttribute = classInstance.GetAttribute<TableNameAttribute>();

        Console.WriteLine(tableNameAttribute != null ? tableNameAttribute.TableName : "null");
        Console.ReadKey(true);
    }
}   
Ryan Mann
  • 5,178
  • 32
  • 42
  • To prevent namespace clashing though, it's best not to extend the System namespace, and use your own instead and just remember to include the namespace when you want the extensions to work. Doing it this way, they'll work anywhere you are using the System namespace, but could easily collide with System signatures in the future, either by microsoft, or by third party depedencies. – Ryan Mann Jun 16 '16 at 19:02