Get MethodInfo for any method with any signature (delegate for any signature)

I want to write a method that will analyze the user attributes of any method (with any number of arguments and any return type), knowing only the information about the method. This function checks if a method has a specific attribute. for example: var tmp = methodInfo.GetCustomAttributes(typeof(LineItemAttribute),false); , and if he has such an attribute, he will execute it. And I want the call to this function to be very easy to use. So, in the example there are three methods and the GetMethodAttributes method 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 this

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

I do not want to use a string representation of method names, since method names can change, for example:

 MethodInfo info = type.GetMethod(name); 

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

+2
reflection c # delegates
Jan 15 '13 at 0:48
source share
2 answers

As Chris Sinclair pointed out in the comment above; you can use a delegate without using reflection trees or expressions to get MethodInfo . The disadvantage is that the compiler cannot output a general parameter, so you need to specify the delegate type to match the signature of this method as follows:

 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: MethodOf<T> to extract MethodInfo from the given Delegate and some AttributeUtils to get a strongly typed user attribute:

 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; } } 
+3
Jan 15 '13 at 12:38
source share

You can do something like this using Expression Trees , where you pass a method using a lambda expression. However, you still need to pass the stub values ​​for the parameters. For a good example of this in action, check out the Moq source code, which makes extensive use of this template to customize layout behavior for unit testing. Just note that this is not a trivial thing to configure. If you need something relatively quick and dirty, the best option is probably string names with a good refactoring tool and / or automatic tests to help deal with renaming problems.

+2
Jan 15 '13 at 1:21
source share



All Articles