获取任何具有任何签名的方法的MethodInfo(任何签名的委托) [英] Get MethodInfo for any method with any signature (delegate for any signature)

查看:141
本文介绍了获取任何具有任何签名的方法的MethodInfo(任何签名的委托)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个方法来分析任何方法的自定义属性(具有任何数量的参数和任何返回类型)只知道方法信息。
此函数将检查方法是否具有特定的属性。像这样: var tmp = methodInfo.GetCustomAttributes(typeof(LineItemAttribute),false); ,如果它有这样的属性它将执行它。我想打电话功能真的很容易使用。所以,在例子中有三种方法和方法 GetMethodAttributes ,我想要调用。

  class Test 
{
public static void Main()
{


public void Test1(){}

public void Test2(int a){}

public void Test3(object a,string c ,布尔d);

public void GetMethodAttributes(MethodInfo mi){}
}

理想情况下,我想写这样的东西

  public static void Main()
{
var t = new Test();
GetMethodAttributes(t.Test1);
GetMethodAttributes(t.Test2);
GetMethodAttributes(t.Test3);
}

我不想使用方法名称的字符串表示作为方法名称可能会改变,如下所示:

  MethodInfo info = type.GetMethod(name); 

我有任何选择吗?基本上,我需要一种方法来使用代理函数来处理不同的代码。

解决方案

As Chris Sinclair 在上述评论中指出,您可以使用代理而不使用反射或表达式树来获取 MethodInfo 。缺点是编译器无法推断通用参数,因此您必须指定委托类型以匹配给定方法的签名,如下所示:

  public class Test 
{
public static void Main()
{
var t = new Test();
CheckMethodAttributes< Action>(t.Test1);
CheckMethodAttributes< Action< int>>(t.Test2);
CheckMethodAttributes< Action< object,string,bool>>(t.Test3);
}

public void Test1(){}

public void Test2(int a){}

public void Test3 a,string c,bool d){}

public static void CheckMethodAttributes< T>(T func)
{
MethodInfo method = new MethodOf< T>(func);

//示例属性检查:
var ignoreAttribute = method.GetAttribute< IgnoreAttribute>();
if(ignoreAttribute!= null)
{
//在这里做某事...
}
}
}

这使用两个实用程序类, MethodOf< T> code> MethodInfo 从给定的委托和一些 AttributeUtils 获得强类型自定义属性检索:

  public static class AttributeUtils 
{
public static bool HasAttribute< TAttribute> MemberInfo成员,bool inherit = true)
其中TAttribute:Attribute
{
return member.IsDefined(typeof(TAttribute),inherit);
}

public static TAttribute GetAttribute< TAttribute>(此MemberInfo成员,bool inherit = true)
其中TAttribute:Attribute
{
return member。 GetAttributes< TAttribute>(inherit).FirstOrDefault();
}

public static IEnumerable< TAttribute> GetAttributes< TAttribute>(此MemberInfo成员,bool inherit = true)
其中TAttribute:Attribute
{
return member.GetCustomAttributes(typeof(TAttribute),inherit).Cast< TAttribute>() ;
}
}

public class MethodOf< T>
{
public MethodOf(T func)
{
var del = func as Delegate;
if(del == null)throw new ArgumentException(Can not convert func to Delegate。,func);

Method = del.Method;
}

private MethodInfo方法{get;组;

public static implicit operator MethodOf< T>(T func)
{
return new MethodOf< T>(func);
}

public static implicit operator MethodInfo(MethodOf< T> methodOf)
{
return methodOf.Method;
}
}


I want to write a method that will analyze custom attributes of any method (with any number of arguments and any return type) knowing only method info. This function will check if method has specific Attribute. like this: var tmp = methodInfo.GetCustomAttributes(typeof(LineItemAttribute),false); and if it has such attribute It will execute it.And I want to make call of that function really easy to use. So, in example there are three methods and method GetMethodAttributes that I want to call.

class Test
{
      public static void Main()
      {
      }

      public void Test1(){}

      public void Test2(int a){}

      public void Test3(object a, string c, Boolean d);

      public void GetMethodAttributes(MethodInfo mi) {}
}

Ideally I want to write something like that

public static void Main()
    {
        var t = new Test();
        GetMethodAttributes(t.Test1);
        GetMethodAttributes(t.Test2);
        GetMethodAttributes(t.Test3);
    }

I don't want to use string representation of the method names as method names may change, like that:

MethodInfo info = type.GetMethod(name);

Do I have any options? Basically I need a way to use delegates for functions with different sinatures

解决方案

As Chris Sinclair pointed out in the comment above; you can use a delegate without using reflection or expression trees to get the MethodInfo. The downside is that the compiler is not able to infer the generic parameter so you have to specify the delegate type to match the signature of the given method like this:

public class Test
{
    public static void Main()
    {
        var t = new Test();
        CheckMethodAttributes<Action>(t.Test1);
        CheckMethodAttributes<Action<int>>(t.Test2);
        CheckMethodAttributes<Action<object, string, bool>>(t.Test3);
    }

    public void Test1() { }

    public void Test2(int a) { }

    public void Test3(object a, string c, bool d) { }

    public static void CheckMethodAttributes<T>(T func)
    {
        MethodInfo method = new MethodOf<T>(func);

        // Example attribute check:
        var ignoreAttribute = method.GetAttribute<IgnoreAttribute>();
        if (ignoreAttribute != null)
        {
            // Do something here...
        }
    }
}

This uses two utility classes, the MethodOf<T> for extracting the MethodInfo from the given Delegate and some AttributeUtils to get strongly typed custom attribute retrieval:

public static class AttributeUtils
{
    public static bool HasAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
        where TAttribute : Attribute
    {
        return member.IsDefined(typeof(TAttribute), inherit);
    }

    public static TAttribute GetAttribute<TAttribute>(this MemberInfo member, bool inherit = true)
        where TAttribute : Attribute
    {
        return member.GetAttributes<TAttribute>(inherit).FirstOrDefault();
    }

    public static IEnumerable<TAttribute> GetAttributes<TAttribute>(this MemberInfo member, bool inherit = true)
        where TAttribute : Attribute
    {
        return member.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>();
    }
}

public class MethodOf<T>
{
    public MethodOf(T func)
    {
        var del = func as Delegate;
        if (del == null) throw new ArgumentException("Cannot convert func to Delegate.", "func");

        Method = del.Method;
    }

    private MethodInfo Method { get; set; }

    public static implicit operator MethodOf<T>(T func)
    {
        return new MethodOf<T>(func);
    }

    public static implicit operator MethodInfo(MethodOf<T> methodOf)
    {
        return methodOf.Method;
    }
}

这篇关于获取任何具有任何签名的方法的MethodInfo(任何签名的委托)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆