如何从Action <T>获取方法的自定义属性?

mbu*_*ill 7 c# reflection

如何从Action<T>委托中获取方法的自定义属性?

例:

//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?
}
Run Code Online (Sandbox Code Playgroud)

我意识到我可以通过在Foo上使用反射来做到这一点,但是对于我想要创建的东西,我必须使用Action<T>.

Mar*_*ell 11

问题是该行动并未直接指向Foo.DoSomething.它指向编译器生成的表单方法:

private static void <>__a(Foo m)
{
    m.DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

这里的一个选项是将其更改为a Expression<Action<T>>,然后您可以解析表达式树并提取属性:

Expression<Action<Foo>> myAction = m => m.DoSomething();
var method = ((MethodCallExpression)myAction.Body).Method;
var statusAttributes = method.GetCustomAttributes<StatusAttribute>(true);
int count = statusAttributes.Count(); // = 1
Run Code Online (Sandbox Code Playgroud)