Search code examples
c#lambdaexpression-trees

Get method name from lambda without call


I'm looking to get hold of a method name from a lambda expression, I'm aware it can be done this way:

GetName(() => MethodA());

My issue is that if MethodA takes any args, you have to supply them just to satisfy the compiler about the expression (after all, how can it know you're not actually executing it?)

I'd like to be able to do:

GetName(() => MethodA);

Is there a way of doing this?


NOTE: This is not a duplicate, this is dealing with a Method Group and not an actual "invocation" of a method.


Solution

  • Certainly. If you have your GetName method take an Expression<Func<Action>> as a parameter, for example, then you can pass () => MethodA into it, as long as MethodA is convertible to the same delegate signature as Action.

    void Main()
    {
        Expression<Func<Action>> x = () => Foo;
        Expression<Func<Func<int>>> y = () => Foo2;
        var xName = ((MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)x.Body).Operand).Object).Value).Name;
    }
    
    void Foo(){}
    int Foo2(){return 0;}
    

    You can write your GetName method to examine the given expression and extract out the name of the method group from it. However, there are two things you should keep in mind.

    1. Even if your lambda expression appears to "call" a method, it's only an expression and won't actually generate a call to that method.
    2. Trying to capture a method group this way will make it very difficult to distinguish between overloaded methods with the same name.

    For that reason, I have to imagine you'd be better off using a more traditional approach that does involve a method call expression.