55

I have a class that look like the following:

public class MyClass
{

...

    protected void MyMethod()
    {
    ...
    string myName = System.Reflection.MethodBase.GetCurrentMethod.Name;
    ...
    }

...

}

The value of myName is "MyMethod".

Is there a way that I can use Reflection to get a value of "MyClass.MyMethod" for myName instead?

Onion-Knight
  • 3,477
  • 7
  • 31
  • 34
  • 2
    Correction: it should be System.Reflection.MethodBase.GetCurrentMethod().Name – aads Sep 26 '13 at 06:33
  • Does this answer your question? [Can you use reflection to find the name of the currently executing method?](https://stackoverflow.com/questions/44153/can-you-use-reflection-to-find-the-name-of-the-currently-executing-method) – Michael Freidgeim Jun 21 '21 at 07:34

8 Answers8

82

You could look at the ReflectedType of the MethodBase you get from GetCurrentMethod, i.e.,

MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();
string methodName = method.Name;
string className = method.ReflectedType.Name;

string fullMethodName = className + "." + methodName;
Ruben
  • 15,217
  • 2
  • 35
  • 45
  • 2
    Just note that the 'ReflectedType' does not account for runtime polymorphism as one might have expected.. – user2864740 Nov 07 '16 at 03:43
  • 1
    In async functions the name is returned as MoveNext. The only answer that addresses names within async functions is https://stackoverflow.com/questions/2968352/using-system-reflection-to-get-a-methods-full-name/48758173#48758173 – Michael Freidgeim Nov 12 '20 at 11:16
27

And to get the full method name with parameters:

var method = System.Reflection.MethodBase.GetCurrentMethod();
var fullName = string.Format("{0}.{1}({2})", method.ReflectedType.FullName, method.Name, string.Join(",", method.GetParameters().Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)).ToArray()));
mms
  • 535
  • 5
  • 7
  • 1
    +1 Definitely the most useful solution. Including the FullName helps pinpoint the class when your code base has repeated class names in different namespaces. And including the parameters helps distinguish between overloaded methods. – Troy Gizzi Feb 05 '15 at 16:18
16

I think these days, it's best to do this:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}";
Peter Kottas
  • 893
  • 13
  • 27
  • 2
    Have been searching for this so that I could log qualified names and this is the approach I ended up adopting. Just because it is small, simple and does what I need. – onesixtyfourth Mar 06 '18 at 07:57
8

Extending Ruben's, you can get the full name like this:

var info = System.Reflection.MethodBase.GetCurrentMethod();
var result = string.Format(
                 "{0}.{1}.{2}()",
                 info.ReflectedType.Namespace,
                 info.ReflectedType.Name,
                 info.Name);

You can add it to a static method that receives a MethodBase parameter and generates the string.

JoanComasFdz
  • 2,911
  • 5
  • 34
  • 50
6

You can get the full name like this:

var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;
DonBoitnott
  • 10,787
  • 6
  • 49
  • 68
user2569050
  • 423
  • 6
  • 5
5

In C# 6 you can use nameof :

string myName = nameof(MyMethod);
Salar
  • 495
  • 3
  • 6
  • 14
  • 2
    Yes, but that returns just the name, not the full name. In the example given, it returns the string `"MyMethod"`, not `"MyClass.MyMethod"`. – Matt May 30 '16 at 12:00
3

You'll have issues when running inside async methods. Here's how to fix that:

If you need to fully qualify the class name, you'll have to use DeclaringType.FullName instead of DeclaringType.Name

This code won't work nicely for anonymous or lambda methods.

using System.Runtime.CompilerServices;

static string GetMethodContextName() {
    var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName();
    return name;
}

static string GetMethodContextName(this MethodBase method) {
    if (method.DeclaringType.GetInterfaces().Any(i => i == typeof(IAsyncStateMachine))) {
        var generatedType = method.DeclaringType;
        var originalType = generatedType.DeclaringType;
        var foundMethod = originalType.GetMethods(
              BindingFlags.Instance | BindingFlags.Static 
            | BindingFlags.Public | BindingFlags.NonPublic 
            | BindingFlags.DeclaredOnly)
            .Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType);
        return foundMethod.DeclaringType.Name + "." + foundMethod.Name;
    } else {
        return method.DeclaringType.Name + "." + method.Name;
    }
}

Here's an example usage:

class Program { 
    static void Main(string[] args) {
        // outputs Program.Main
        Console.WriteLine(GetMethodContextName());
    }
}
Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
bboyle1234
  • 4,859
  • 2
  • 24
  • 29
2

Thanks for the posts above, they helped me to create a strong type binding system for MVC 4 HTMLHelpers as follows.

 public static MvcHtmlString StrongTypeBinder(this HtmlHelper htmlhelper, Expression<Func<object, string>> SomeLambda)
    {
        var body = SomeLambda.Body;
        var propertyName = ((PropertyInfo)((MemberExpression)body).Member).Name;
        HtmlString = @"
            <input type='text' name='@Id' id='@Id'/>
            ";
        HtmlString = HtmlString.Replace("@Id", propertyName);
        var finalstring = new MvcHtmlString(HtmlString);
        return finalstring;

    }

To use the code above in any CSHTML View:

@Html.StrongTypeBinder(p=>Model.SelectedDate)

This allows me to bind any property in a ViewModel to any HTML element type I want. In the example above, I an binding the name field for the selected data posted back after user makes selection. The viewmodel after the post back automatically shows the selected value.

JWP
  • 6,672
  • 3
  • 50
  • 74