500

I know you can do

this.GetType().FullName

To get

My.Current.Class

But what can I call to get

My.Current.Class.CurrentMethod
Hille
  • 2,123
  • 22
  • 39
Nick Allen
  • 11,970
  • 11
  • 45
  • 58
  • 11
    `this.ToString()` gives you the current classname only when you've not done anything special in your own `public override string ToString()`. `GetType().FullName` does give you full name always. – Pasi Savolainen Apr 16 '10 at 11:28
  • @Pasi thanks, will change my implementation – Nick Allen Apr 16 '10 at 11:45
  • 6
    In .Net 4.5, you can use CallerMemberNameAttribute to get the name of the caller. See https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx ... You can then wrap the body of your function in an anonymous function as in ([CallerMemberName] string functionName = "")=>{ }. The problems with using the reflection method as in the accepted answer are that (1) the function may be inlined, and/or (2) the function name may be obfuscated if it is non-public and the code is obfuscated. – GreatAndPowerfulOz Mar 04 '16 at 22:08
  • 2
    Not really a duplicate question. The original question asks specifically about 'reflection'. Some of the answers here are not based on reflection. – James John McGuire 'Jahmic' Sep 25 '19 at 15:33
  • To support async methods you can use GetCurrentMethodFullName() from [Using System.Reflection to Get a Method's Full Name](//stackoverflow.com/a/48758173) – Michael Freidgeim Jun 21 '21 at 23:02

7 Answers7

651

Call System.Reflection.MethodBase.GetCurrentMethod().Name from within the method.

Jamie Ide
  • 48,427
  • 16
  • 81
  • 117
  • 5
    Does this suffer from inlining? – Gusdor Jun 23 '16 at 12:21
  • 14
    If you're wondering which one is faster, Reflection or StackTrace check this: https://stackoverflow.com/a/1348853/495455 – Jeremy Thompson May 26 '17 at 02:10
  • 1
    Just make sure you add [MethodImpl(MethodImplOptions.NoInlining)] as a decorator to the method from which you call this otherwise it doesn't work. Thanks – erionpc Dec 19 '17 at 08:58
  • 15
    @Konrad In the post `StackTrace` yields signficantly slower results. The only scenario where it yields faster results is when reflection is compared to nothing. Using BenchmarkDotNet I tested `MethodBase.GetCurrentMethod().Name` versus `new StackFrame(0).GetMethod().Name`, where reflection used on average 1.5us while `StackTrace` used 11.5us. – NotFound Jan 21 '19 at 10:04
  • @Bleep-Bloop it depends, the post has many ifs. – Konrad Jan 21 '19 at 18:46
  • @Konrad The conclusion of the post you linked to is not that StackTrace is faster (they show that it's much _slower_). The reason they used StackTrace was because they can skip it in their specific scenario when logging is disabled. Your blanket claim that StackTrace is faster is extremely misleading. – Kevin Jun 20 '23 at 00:42
441
using System.Diagnostics;
...

var st = new StackTrace();
var sf = st.GetFrame(0);

var currentMethodName = sf.GetMethod();

Or, if you'd like to have a helper method:

[MethodImpl(MethodImplOptions.NoInlining)]
public string GetCurrentMethod()
{
    var st = new StackTrace();
    var sf = st.GetFrame(1);

    return sf.GetMethod().Name;
}

Updated with credits to @stusmith.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
  • 68
    Bear in mind the JIT is free to inline methods, which might throw this off. To force a method to not be inlined, add the [MethodImpl(MethodImplOptions.NoInlining)] attribute. – stusmith Apr 16 '10 at 11:29
  • 40
    Note that adding `MethodImpl(MethodImplOptions.NoInlining)` to `GetCurrentMethod` only stops that method from being inlined into its caller. It doesn't prevent the calling method itself from being inlined into its own caller etc, etc. – LukeH Apr 16 '10 at 12:23
  • @Luke: That is of course possible and complicates things. –  Apr 16 '10 at 12:26
  • Sorry yes I wasn't clear - you need to add the attribute to the method for which you want to know the name of. – stusmith Apr 16 '10 at 13:44
  • @stusmith: The GetCurrentMethod would need the attribute as well, right? It could also become inlined why not. –  Apr 16 '10 at 13:48
  • 4
    FYI, this does not compile as `sf.GetMethod()` is not a string. – Hamish Grubijan May 03 '12 at 18:50
  • Does this method always return "GetCurrentMethod" since it's pushed on top of the caller on the stack when we really want to return the name of the caller? – Candy Chiu Jul 25 '12 at 20:17
  • @CandyChiu, no. Note that they are getting the second frame (`GetFrame(1)`) – Jonathon Reinhart Aug 07 '12 at 00:24
  • @Hamish: The helper method has a mistake in the last line. It should probably read something like `return sf.GetMethod().Name`. As pointed out by @LukeH above, if you want this to be bulletproof I suspect you also need to mark any method that calls it with `MethodImpl(MethodImplOptions.NoInlining)` (unless you're sure it won't be inlined (e.g. a method exposed as `public`) – rkagerer Jan 15 '13 at 20:51
  • re: the upvoted comment by @stusmith -- I saw [somewhere else](http://blogs.msdn.com/b/webdevelopertips/archive/2009/06/23/tip-83-did-you-know-you-can-get-the-name-of-the-calling-method-from-the-stack-using-reflection.aspx#9801326) that the attribute `[MethodImpl(...NoInlining)]` doesn't always work if the _compiler_ optimizes away the StackTrace – drzaus Jan 22 '14 at 20:03
  • I've not managed to find a solution that works with release code. In debug mode the inlining is not so aggressive and `[MethodImpl(MethodImplOptions.NoInlining)]` seems to work well, but when I change to release mode, all bets seem to be off and `NoInlining` seems to be treated as a hint? – snowcode Nov 05 '14 at 14:33
  • 1
    Just spoke to collegue who pointed out that my problem was because I was not putting `NoInlining` on all of the callers all the way up the tree. Doh! (of course!) This is annoying since most of the use cases where I've needed `GetMethod()` are acceptance test helpers, and requiring all the callers to have `NoInlining` makes the code messy, less easy to scan. Anyway, my collegues comment explained why my code was sometimes being Inlined despite marking the method with the attribute. I've not deleted my comment above, in case someone else has the same problem. – snowcode Nov 05 '14 at 16:40
  • 35
    C# version 6 have new feature `nameof()` which can be used for this purpose too: `nameof(this.YourCurrentMethod);` [https://msdn.microsoft.com/en-us/library/dn986596.aspx](https://msdn.microsoft.com/en-us/library/dn986596.aspx) – Fabio Feb 06 '16 at 07:37
  • 13
    And then there is CallerMemberNameAttribute http://stackoverflow.com/a/15310053/58768 – bohdan_trotsenko Mar 17 '16 at 14:33
  • This assumes the stack position of the current method and is not reliable. The solution by Jamie Ide is the correct one. – Antony Booth Sep 14 '16 at 14:44
  • 1
    @AntonyBooth, Look at the comment above you - it's better. (Uses the [CallerMemberName] and can be used in a static method to get it anywhere) – Ori Nachum Jan 18 '17 at 17:08
  • This doesn't appear to work if the method has a return type of Task, you need to use GetFrame(3). GetFrame(1) is MoveNext, GetFrame(2) is start. e.g. public async Task TestMigrateData() – Justin Feb 25 '19 at 16:59
  • Not work at UWP apps – HelloWindowsPhone Jun 16 '19 at 14:37
  • you can just use `new StackFrame().GetMethod()`, it's shorter than `new StackTrace().GetFrame(0).GetMethod()` and does the same thing. – Jason C May 25 '21 at 02:02
183

Since C# version 6 you can simply call:

string currentMethodName = nameof(MyMethod);

In C# version 5 and .NET 4.5 you can use the [CallerMemberName] attribute to have the compiler auto-generate the name of the calling method in a string argument. Other useful attributes are [CallerFilePath] to have the compiler generate the source code file path and [CallerLineNumber] to get the line number in the source code file for the statement that made the call.


Before that there were still some more convoluted ways of getting the method name, but much simpler:

void MyMethod() {
  string currentMethodName = "MyMethod";
  //etc...
}

Albeit that a refactoring probably won't fix it automatically.

If you completely don't care about the (considerable) cost of using Reflection then this helper method should be useful:

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Reflection;
//...

[MethodImpl(MethodImplOptions.NoInlining)]
public static string GetMyMethodName() {
  var st = new StackTrace(new StackFrame(1));
  return st.GetFrame(0).GetMethod().Name;
} 
Neuron
  • 5,141
  • 5
  • 38
  • 59
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I've done this before. Can be a sod to maintain if you do this application-wide, but otherwise: Simple beats clever any day! – Daren Thomas Apr 16 '10 at 12:33
  • 3
    True words, it is about 10,000 times faster, give or take a factor of 10. – Hans Passant Apr 16 '10 at 12:51
  • CallerMemberName will not work for overloaded methods. – Onur Omer Sep 04 '15 at 21:19
  • 4
    It seems to me your second answer should be a *second reply* and [not an edit](http://meta.stackoverflow.com/a/314024/282105). Right now your second answer is hidden in a big reply and the reader might miss the second part. – SandRock Jan 13 '16 at 10:02
  • 17
    C# version 6 have new feature `nameof()` which can be used for this purpose too: `nameof(this.YourCurrentMethod);` [https://msdn.microsoft.com/en-us/library/dn986596.aspx](https://msdn.microsoft.com/en-us/library/dn986596.aspx) – Fabio Feb 06 '16 at 07:37
  • Hans, why this answer uses more shorter version? https://stackoverflow.com/a/44215/2377343 – T.Todua Sep 27 '17 at 18:34
  • Because that answer does not use a separate method like I did. – Hans Passant Sep 27 '17 at 19:28
  • Is there a modern short-hand call for the name of the class the method belongs to, like in the Update 2? – ajeh Apr 13 '18 at 13:53
  • `CallerMemberName` works for .NETCore 2.0 in Async methods. Perfect. – Andy Apr 22 '18 at 04:38
49

I think the best way to get the full name is:

 this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

or try this

string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);   
Zakaria
  • 1,055
  • 12
  • 16
  • 1
    +1 because using reflection is several order of magnitude faster than using StackTrace. – Giuseppe Romagnuolo Feb 07 '14 at 22:53
  • 25
    This does not work for `async` methods. I call `System.Reflection.MethodBase.GetCurrentMethod().Name` on the first line of a method and I get `MoveNext`. – Gusdor Jun 23 '16 at 12:34
  • 1
    Is it possible to create function which will return callers function class/name? Your solution is great, but a little long to be called each time. It would be ideal if this can be on some other class and public function or perhaps public property which can be called. Ideally in some static class. – FrenkyB Sep 30 '16 at 07:39
  • 2
    @FrenkyB - Use [CallerMemberName] attribute on a helper function. – andrew Nov 10 '17 at 04:42
  • For ```async``` methods, I have added an answer here https://stackoverflow.com/questions/44153/can-you-use-reflection-to-find-the-name-of-the-currently-executing-method/67372375#67372375 – Useme Alehosaini May 03 '21 at 16:45
  • Since C# version 6 you can use `this.GetType().FullName + "." + nameof(MyMethod)` and benefit from refactoring convenience. – Guney Ozsan Oct 29 '21 at 14:31
13

Does this not work?

System.Reflection.MethodBase.GetCurrentMethod()

Returns a MethodBase object representing the currently executing method.

Namespace: System.Reflection

Assembly: mscorlib (in mscorlib.dll)

http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod.aspx

Orwellophile
  • 13,235
  • 3
  • 69
  • 45
10

You can also use MethodBase.GetCurrentMethod() which will inhibit the JIT compiler from inlining the method where it's used.


Update:

This method contains a special enumeration StackCrawlMark that from my understanding will specify to the JIT compiler that the current method should not be inlined.

This is my interpretation of the comment associated to that enumeration present in SSCLI. The comment follows:

// declaring a local var of this enum type and passing it by ref into a function 
// that needs to do a stack crawl will both prevent inlining of the calle and 
// pass an ESP point to stack crawl to
// 
// Declaring these in EH clauses is illegal; 
// they must declared in the main method body
João Angelo
  • 56,552
  • 12
  • 145
  • 147
  • Do you have a reference explaining how `GetCurrentMethod` inhibits the JIT from inlining the calling method? – LukeH Apr 16 '10 at 12:19
  • @Luke, I updated my answer with the reason why I believe the method will inhibit the inlining. – João Angelo Apr 16 '10 at 13:37
  • Thanks, that's very interesting, although it's not entirely clear to me whether it prevents inlining of the method that declares the local `StackCrawlMark` or the caller of that method. – LukeH Apr 16 '10 at 14:18
  • @Luke, yes it can cast a certain doubt, but since `GetCurrentMethod` itself is decorated with `[MethodImpl(MethodImplOptions.NoInlining)]` I believe it's the caller of the method containing the enumeration. – João Angelo Apr 16 '10 at 14:20
6

Well System.Reflection.MethodBase.GetCurrentMethod().Name is not a very good choice 'cause it will just display the method name without additional information.

Like for string MyMethod(string str) the above property will return just MyMethod which is hardly adequate.

It is better to use System.Reflection.MethodBase.GetCurrentMethod().ToString() which will return the entire method signature...

Arefin
  • 69
  • 1
  • 1