JoelFan
JoelFan

Reputation: 38704

function to get the name of any method?

I would like to have a function called GetMethodName such that the following code would print "myMethod":

int myMethod(string foo, double bar)
{
    // ...
}

Console.Out.WriteLine(GetMethodName(myMethod));

This should work no matter what the method signature myMethod has. Is this possible?

Upvotes: 4

Views: 585

Answers (6)

Matthew Whited
Matthew Whited

Reputation: 22433

As pointed out on Eric Lippert's blog you could fake it with the Action and Func delegates

public static MethodInfo GetInfo<T>(Action<T> action)
{
    return action.Method;
}
public static MethodInfo GetInfo<T, TResult>(Func<T, TResult> func)
{
    return func.Method;
}
public static MethodInfo GetInfo<T, U, TResult>(Func<T, U, TResult> func)
{
    return func.Method;
}   
public static int Target(int v1, int v2)
{
    return v1 ^ v2;
} 
static int Main(string[] args)
{
    var mi = GetInfo<string[], int>(Main);
    Console.WriteLine(mi.Name);

    var mi2 = GetInfo<int, int, int>(Target);
    Console.WriteLine(mi2.Name);
    return 0;
}

Upvotes: 5

JoelFan
JoelFan

Reputation: 38704

What about this?

public static string GetMethodName(Expression<Action> exp)
{
    var b = (MethodCallExpression)exp.Body;
    return b.Method.Name;
}

// ...


var name = GetMethodName(() => myMethod(string.Empty, 0.0));
System.Out.WriteLine(name);

Upvotes: 2

Mircea Grelus
Mircea Grelus

Reputation: 2915

EDIT: Misunderstood the question. It actually helps reading the question.

You can use Reflection:

MethodBase.GetCurrentMethod returns the current running method.

Upvotes: -1

Codism
Codism

Reputation: 6224

Yes it is doable. Look at class StackFrame and its GetMethod.

EDIT: looks like I misunderstood the original question. Never mind my original answer.

Upvotes: -2

Jon Skeet
Jon Skeet

Reputation: 1499860

No, it's not possible like that. It would be possible with the mythical infoof operator which the C# team would like to include, but haven't got round to yet - but without that, you'd have to use a method group conversion, which will only work if you know the specific type of delegate to use.

The closest you can probably come is to use an expression tree:

public static string GetMethodName(Expression expression)
{
    // Code to take apart the expression tree and find the method invocation
}

GetMethodName(() => myMethod(0, 0));

That wouldn't actually need to call myMethod, but you would need to provide dummy arguments - which could be irritating if there are any out/ref parameters.

Upvotes: 11

Wil P
Wil P

Reputation: 3371

Something like the below?

new StackFrame(1, false).GetMethod().Name

:Edit to add code sample...

    public string PrintMethodName()
    {
        return new StackFrame(1, false).GetMethod().Name;
    }

    private void Hi()
    {
        Console.WriteLine(PrintMethodName());
    }

Upvotes: -1

Related Questions