Passing methods to expressions with their called values
You can use the GetMemberFromExpression method as it is, and then simply remove the Generic parameter. As below:
static void Main(string[] args) { var memberInfo1 = GetMemberFromExpression(() => Method1(10, 20)); var memberInfo2 = GetMemberFromExpression(() => Method2()); var memberInfo3 = GetMemberFromExpression(() => Method3("string", 15, DateTime.Now)); Console.WriteLine(memberInfo1.Name); Console.WriteLine(memberInfo2.Name); Console.WriteLine(memberInfo3.Name); Console.Read(); } public static MemberInfo GetMemberFromExpression(Expression<Action> expression) { return ((MethodCallExpression)expression.Body).Method; } public static object Method1(int p1, int p2) { return p1 + p2; } public static void Method2() {
You will see that GetMemberFromExpression will return MethodInfo any method you pass, regardless of the type or type of the parameter and the type of return.
Ignore overloads, call by name and name
If you're not worried about overloads, you can probably use simple reflection instead of creating expressions. A nameof operator in C # 6 would be a better approach than passing a name as a string (compile time checking).
public static MemberInfo GetMemberInfo(Type type, string methodName) { return type.GetMethod(methodName); }
Please note: there are no validation checks in this method, just to show the concept.
The above method will work for any instance or static methods. Just pass an instance type type / or a static class type and a method name as follows:
MyClass cl = new MyClass(); var methodInfo1 = GetMemberInfo(cl.GetType(), "AMethod"); var methodInfo2 = GetMemberInfo(typeof(MyClass), "AStaticMethod");
Here's MyClass using methods:
class MyClass { public void AMethod(int a, int b) {
This way you are not passing any parameters, because you are just studying the definition and not calling.
Using expressions with types rather than values
Here is the third option. So you have:
- Check compilation time,
- No need to pass valuable ("fake") parameters,
- Only the required parameter types are required (which ensures that overloaded methods will work).
Create a class that serves Action and Func overloads:
public class Method { public static MethodInfo GetInfo<TReturn>(Func<TReturn> method) { return method.Method; } public static MethodInfo GetInfo<TP1, TReturn>(Func<TP1, TReturn> method) { return method.Method; } public static MethodInfo GetInfo<TP1, TP2, TReturn>(Func<TP1, TP2, TReturn> method) { return method.Method; }
Now you can simply get your MethodInfo as follows:
var methodInfo1 = Method.GetInfo<int, int>(cl.AMethod); var methodInfo2 = Method.GetInfo<bool, bool, bool>(MyClass.AStaticMethod);
Yes, you need to create a bunch of overloads in the Method class for Action and Func , but that will not be correct, and you will do the same with .NET Action and Func to serve all overloads.