Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从操作中获取方法的自定义属性<;T>;?_C#_Reflection - Fatal编程技术网

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.

问题在于lambda
m=>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);
}