Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the custom attributes of a method from Action<T>?

Tags:

c#

reflection

How can I get the custom attributes of a method from a Action<T> delegate?

Example:

//simple custom attribute
public class StatusAttribute : Attribute
{

    public string Message { get; set; } = string.Empty;
}

// an extension methodto wrap MethodInfo.GetCustomAttributes(Type, Bool) with
// generics for the custom Attribute type
public static class MethodInfoExtentions
{
    public static IEnumerable<TAttribute> GetCustomAttributes<TAttribute>(this MethodInfo methodInfo, bool inherit) where TAttribute : Attribute
    {
        object[] attributeObjects = methodInfo.GetCustomAttributes(typeof(TAttribute), inherit);
        return attributeObjects.Cast<TAttribute>();
    }
}

// test class with a test method to implment the custom attribute
public class Foo
{
    [Status(Message="I'm doing something")]
    public void DoSomething()
    {
        // code would go here       
    }
}

// creates an action and attempts to get the attribute on the action
private void CallDoSomething()
{
    Action<Foo> myAction = new Action<Foo>(m => m.DoSomething());
    IEnumerable<StatusAttribute> statusAttributes = myAction.Method.GetCustomAttributes<StatusAttribute>(true);

    // Status Attributes count = 0? Why?
}

I realize I could do this by using reflection on Foo, but for what I'm trying to create I have to use an Action<T>.

like image 497
mbursill Avatar asked Jan 27 '11 22:01

mbursill


People also ask

How do I find custom attributes?

Right-click on a user, then click Properties. Click the Attribute Editor tab, then confirm that the custom attribute you created is listed in the "Attribute" column (e.g., LastPassK1).

Which method is used to retrieve the values of the attributes?

First, declare an instance of the attribute you want to retrieve. Then, use the Attribute. GetCustomAttribute method to initialize the new attribute to the value of the attribute you want to retrieve. Once the new attribute is initialized, you can use its properties to get the values.

What is custom attribute in C#?

The class name AuthorAttribute is the attribute's name, Author , plus the Attribute suffix. It is derived from System. Attribute , so it is a custom attribute class. The constructor's parameters are the custom attribute's positional parameters.

What are custom attributes?

A custom attribute is a property that you can define to describe assets. Custom attributes extend the meaning of an asset beyond what you can define with the standard attributes. You can create a custom attribute and assign to it a value that is an integer, a range of integers, or a string.


1 Answers

The problem is that the action doesn't directly point at Foo.DoSomething. It points at a compiler-generated method of the form:

private static void <>__a(Foo m)
{
    m.DoSomething();
}

One option here would be to change it to an Expression<Action<T>>, then you can dissect the expression tree afterwards and extract the attributes:

Expression<Action<Foo>> myAction = m => m.DoSomething();
var method = ((MethodCallExpression)myAction.Body).Method;
var statusAttributes = method.GetCustomAttributes<StatusAttribute>(true);
int count = statusAttributes.Count(); // = 1
like image 78
Marc Gravell Avatar answered Sep 20 '22 15:09

Marc Gravell