Get the name of a method using an expression

Andre picture Andre · Nov 22, 2011 · Viewed 15.4k times · Source

I know there are a few answers on the site on this and i apologize if this is in any way duplicate, but all of the ones I found does not do what I am trying to do.

I am trying to specify method info so I can get the name in a type safe way by not using strings. So I am trying to extract it with an expression.

Say I want to get the name of a method in this interface:

public interface IMyInteface
{
    void DoSomething(string param1, string param2);
}

Currently I can get the name using THIS method:

 MemberInfo GetMethodInfo<T>(Expression<Action<T>> expression)
 {
        return ((MethodCallExpression)expression.Body).Method;
 }

I can call the helper method as follows:

var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething(null, null));
Console.WriteLine(methodInfo.Name);

But I am looking for the version that I can get the method name without specifying the parameters (null, null)

like this:

var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething);

But all attempts fail to compile

Is there a way to do this?

Answer

Snowbear picture Snowbear · Nov 22, 2011
x => x.DoSomething

In order to make this compilable I see only two ways:

  1. Go non-generic way and specify it's parameter as Action<string, string>
  2. Specify Action<string, string> as your target delegate type by yourself: GetMethodInfo<IMyInteface>(x => new Action<string,string>(x.DoSomething))

if you are ok to go with second one, which allows you to omit arguments then you can write your GetMethodInfo method as follows:

    MemberInfo GetMethodInfo<T>(Expression<Func<T, Delegate>> expression)
    {
        var unaryExpression = (UnaryExpression) expression.Body;
        var methodCallExpression = (MethodCallExpression) unaryExpression.Operand;
        var methodInfoExpression = (ConstantExpression) methodCallExpression.Arguments.Last();
        var methodInfo = (MemberInfo) methodInfoExpression.Value;
        return methodInfo;
    }

It works for your interface, but probably some generalization will be required to make this working with any method, that's up to you.