如何从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)