C# 如何从操作中获取方法的自定义属性<;T>;?
如何从C# 如何从操作中获取方法的自定义属性<;T>;?,c#,reflection,C#,Reflection,如何从操作委托中获取方法的自定义属性 例如: //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
操作
委托中获取方法的自定义属性
例如:
//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?
}
//简单自定义属性
公共类StatusAttribute:属性
{
公共字符串消息{get;set;}=string.Empty;
}
//一个扩展MethodInfo.GetCustomAttributes(Type,Bool)的包装方法
//自定义属性类型的泛型
公共静态类MethodInfoExtensions
{
公共静态IEnumerable GetCustomAttributes(此MethodInfo MethodInfo,bool inherit),其中tatAttribute:Attribute
{
object[]attributeObjects=methodInfo.GetCustomAttributes(typeof(tatAttribute),inherit);
返回attributeObjects.Cast();
}
}
//使用测试方法实现自定义属性的测试类
公开课Foo
{
[状态(Message=“我正在做某事”)]
公共无效剂量测定法()
{
//代码将放在这里
}
}
//创建一个动作并尝试获取该动作的属性
私有void CallDoSomething()
{
动作myAction=新动作(m=>m.DoSomething());
IEnumerable statusAttributes=myAction.Method.GetCustomAttributes(true);
//状态属性计数=0?为什么?
}
我意识到我可以通过使用Foo上的反射来实现这一点,但对于我试图创建的内容,我必须使用
操作,问题是该操作没有直接指向Foo.DoSomething
。它指向编译器生成的以下形式的方法:
private static void <>__a(Foo m)
{
m.DoSomething();
}
private static void\uu a(Foo m)
{
m、 DoSomething();
}
这里的一个选项是将其更改为表达式
,然后您可以随后解析表达式树并提取属性:
Expression<Action<Foo>> myAction = m => m.DoSomething();
var method = ((MethodCallExpression)myAction.Body).Method;
var statusAttributes = method.GetCustomAttributes<StatusAttribute>(true);
int count = statusAttributes.Count(); // = 1
表达式myAction=m=>m.DoSomething();
var method=((MethodCallExpression)myAction.Body);
var statusAttributes=method.GetCustomAttributes(true);
int count=statusAttributes.count();//=1.
问题在于lambdam=>m.DoSomething()
与DoSomething
不同。这是一个lambda表达式,它被编译成编译器生成的方法的方法调用,可能使用编译器生成的类型(尽管可能不是后者,因为没有捕获的局部变量)
从Foo
类型的实例(非静态)方法获取操作的一种非常详细的方法是:
var myAction = (Action<Foo>)Delegate.CreateDelegate(
typeof(Action<Foo>),
null, // treat method as static, even though it's not
typeof(Foo).GetMethod("DoSomething", BindingFlags.Instance | BindingFlags.Public)
);
这将允许您执行以下操作:
Action<Foo> myAction = new Action(new Foo().DoSomething).ToStaticMethod<Foo>();
但这是一个棘手的命题,因为一个任意的表达式
不能保证像m=>m.DoSomething()
以前的答案(除了@Marc Gravell)一样简单♦ '(没有用户代码)似乎是可编译的:)
因此,我建议:
private static void CallDoSomething()
{
var f = new Foo();
Action myAction = f.DoSomething;
IEnumerable<StatusAttribute> statusAttributes = myAction.Method.GetCustomAttributes<StatusAttribute>(true);
}
private静态void CallDoSomething()
{
var f=新的Foo();
动作myAction=f.剂量测定;
IEnumerable statusAttributes=myAction.Method.GetCustomAttributes(true);
}
这里的问题是必须将方法包装到委托。您可以将变量myAction
声明为委托类型。但是,在这种情况下,您必须实例化委托
类型(例如操作
),因此它没有意义。此外,还有许多可编译的解决方案-1美元。
Action<Foo> myAction = m => m.DoSomething();
Expression<Action<Foo>> myExpression = m => m.DoSomething();
private static void CallDoSomething()
{
var f = new Foo();
Action myAction = f.DoSomething;
IEnumerable<StatusAttribute> statusAttributes = myAction.Method.GetCustomAttributes<StatusAttribute>(true);
}