Passing methods to expressions with their invoked values
You can use the GetMemberFromExpression
method as you have it, and then simply remove the Generic parameter. As follows:
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()
{
// No return
}
public static double Method3(string p1, int p2, DateTime p3)
{
return 10d;
}
You'll see that the GetMemberFromExpression
will return MethodInfo
of any method you pass it, regardless or parameter type and return type.
Ignoring overloads, invoking on instance and name
If you're not concerned about overloads, you could probably use simple reflection instead of building up Expressions. The nameof
operator in c# 6 would be a better approach than passing in the name as a string (compile-time checking).
public static MemberInfo GetMemberInfo(Type type, string methodName)
{
return type.GetMethod(methodName);
}
Note, theres no validation checks in this method, just to show the concept.
The above method will work for any instance or static methods. Simply pass the instance type / or static class type and the method name as follows:
MyClass cl = new MyClass();
var methodInfo1 = GetMemberInfo(cl.GetType(), "AMethod");
var methodInfo2 = GetMemberInfo(typeof(MyClass), "AStaticMethod");
Here's MyClass
with the methods:
class MyClass
{
public void AMethod(int a, int b)
{
// instance method
}
public static bool AStaticMethod(bool a, bool b)
{
return a & b; // static method
}
}
This way you don't pass any parameters because you're simply investigating the definition and not invoking.
Using Expressions with types rather than values
Here's a third option. This way you have:
- Compile-time checking,
- No need to pass valued ("fake") parameters,
- Only the parameter types required (which ensures overloaded methods will work).
Create a class catering for the 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;
}
//... Continue with some more Func overloads
public static MethodInfo GetInfo(Action method)
{
return method.Method;
}
public static MethodInfo GetInfo<TP1>(Action<TP1> method)
{
return method.Method;
}
public static MethodInfo GetInfo<TP1, TP2>(Action<TP1, TP2> method)
{
return method.Method;
}
//... Continue with some more Action overloads
}
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'll have to create a bunch of overloads in the Method
class for Action
and Func
, but that's a once off thing you'll do and .NET does the same with the Action
and Func
delegates to cater for all the overloads.
MethodInfo
, why can't you just process the type parameterT
directly? Why the expression at all? – Antirrhinum