39

Is it possible to print the class name from within a static function?

e.g ...

public class foo
{

    static void printName()
    {
        // Print the class name e.g. foo
    }

}
TK.
  • 46,577
  • 46
  • 119
  • 147
  • Does this answer your question? [.NET: Determine the type of “this” class in its static method](https://stackoverflow.com/questions/2081612/net-determine-the-type-of-this-class-in-its-static-method) – Michael Freidgeim Nov 24 '19 at 09:04

7 Answers7

78

You have three options to get the type (and therefore the name) of YourClass that work in a static function:

  1. typeof(YourClass) - fast (0.043 microseconds)

  2. MethodBase.GetCurrentMethod().DeclaringType - slow (2.3 microseconds)

  3. new StackFrame().GetMethod().DeclaringType - slowest (17.2 microseconds)


If using typeof(YourClass) is not desirable, then MethodBase.GetCurrentMethod().DeclaringType is definitely the best option.

Jamezor
  • 2,488
  • 3
  • 23
  • 16
22
Console.WriteLine(new StackFrame().GetMethod().DeclaringType);
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
11

While the StackTrace answers are correct, they do have an overhead. If you simply want safety against changing the name, consider typeof(foo).Name. Since static methods can't be virtual, this should usually be fine.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    That's a good point. Obviously if you control the method then you control the class name, so the whole thing's a bit academic. – Matt Hamilton Feb 16 '09 at 09:02
  • All I am using this for is to Log exceptional behaviour, so I can live with the overhead of using the Stack Trace Method as execution will (probably) cease after this logging activity. – TK. Feb 16 '09 at 09:24
  • 1
    this one will not work if the code is pasted to another class and you forgot that you have this code – Louis Rhys Feb 17 '12 at 11:05
  • 1
    or moved. Let's say the `typeof(foo).Name` or `typeof(foo).Something` code is part of a larger logic, and at some point you decide that the logic is better done in another class. You will not notice that you need to change this because the code will still compile – Louis Rhys Feb 17 '12 at 11:12
  • @Louis Lots of things that compile aren't right. That is why we test. Doing a stack-frame lookup is *not* an efficient way of doing this. – Marc Gravell Feb 17 '12 at 11:15
6

A (cleaner, IMO) alternative (still slow as hell and I would cringe if I saw this in a production code base):

Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType);

By the way, if you're doing this for logging, some logging frameworks (such as log4net) have the ability built in. And yes, they warn you in the docs that it's a potential performance nightmare.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
5

Since C# 6.0 there exists an even simpler and faster way to get a type name as a string without typing a string literal in your code, using the nameof keyword:

public class Foo
{
    static void PrintName()
    {
        string className = nameof(Foo);
        ...
    }
}
2

StackTrace class can do that.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
0

Since static methods cannot be inherited the class name will be known to you when you write the method. Why not just hardcode it?

Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • static methods can be inherited tough., and if you want to call the subclasse's static method you would be out of luck – systemkern Jan 05 '15 at 14:05
  • 1
    @systemkern - Sorry, I didn't understand that. Even if you call the method "through" a subclass (like `SubClass.BaseClassStaticMethod();`), the actual IL code will still be like you called it from the base class. It's just a syntax sugar by the C# compiler. There's no way to _actually_ call a method "through a subclass", and thus no way from within the method to find out that the calling C# code was written like that. – Vilx- Jan 05 '15 at 22:10
  • Yes that is true BUT that could be exactly the point you might want to have slightly different behaviour if you call SubClassAA.BaseClassStaticMethod() than if you call SubClassBB.BaseClassStaticMethod(). This might not be pretty but sometimes neccessary because you do not have full control over the Subclass ... because of "reasons" – systemkern Jan 07 '15 at 06:22
  • @systemkern - Well then, you're screwed. You can't do that. Try coming up with something else, like an instance method or an extension or an extra (type?) parameter or something. Anyways, how does this go against what I wrote? – Vilx- Jan 07 '15 at 11:41
  • i was hung up on the statement that static methods cannot be inherited. – systemkern Jan 20 '15 at 12:56
  • I agree; doesn't any method that uses the actual name of the class ("nameOf()", "typeOf()", et. al.) defeat the purpose of a generic solution insulated from class name change? So could hard-code it in a static/read-only var to work for static and instance cases, and only set once. – galaxis Nov 28 '22 at 20:49