.Net: Determine the Type of "This" Class in Its Static Method

.NET: Determine the type of “this” class in its static method

If you're looking for a 1 liner that is equivalent to this.GetType() for static methods, try the following.

Type t = MethodBase.GetCurrentMethod().DeclaringType

Although this is likely much more expensive than just using typeof(TheTypeName).

How to get the class Type in a base class static method in .NET?

Static methods are not inherited.

The compiler substitutes BaseClass for DerivedClass when calling a base class' static methods through one of its derived classes. For example, here's the IL code for a call to DerivedClass.GetType():

IL_0002:  call   class [mscorlib]System.Type Tests.Program/BaseClass::GetType()

Is there a way to determine which class called a static method in .NET

This all smells from afar. You can have this in many ways, but detecting the calling class is the wrong way.

Either make a different static method for this specific other class, or have an additional argument.

If you insist on detecting the caller, this can be done in several ways:

  1. Use the stack trace:

    var stackFrame = new StackFrame(1);
    var callerMethod = stackFrame.GetMethod();
    var callingClass = callerMethod.DeclaringType; // <-- this should be your calling class
    if(callingClass == typeof(myClass))
    {
    // do whatever
    }
  2. If you use .NET 4.5, you can have caller information. Not specifically the class, but you can get the caller name and source file at the time of compilation. Add a parameter with a default value decorated with [CallerMemberName] or [CallerFilePath], for example:

    static MyMethod([CallerFilePath]string callerFile = "")
    {
    if(callerFile != "")
    {
    var callerFilename = Path.GetFileName(callerFile);
    if(callerFilename == "myClass.cs")
    {
    // do whatever
    }
    }
    }
  3. Simply use an additional parameter with a default value (or any kind of different signature)

Note that 1 is very slow, and 2 is just awful... so for the better yet: use a different method if you need a different process

Update


After watching your code, it's even more clear that you want to have either two different methods or an argument... for example:

public static string GenerateChecks(List<CheckJob> checkJobs, bool throwOnError = true)
{
//...
catch (Exception ex)
{
if(throwOnError)
{
if (Transaction.IsInTransaction)
{
Transaction.Rollback();
}
throw;
}
}
}

And then pass false to that when you want to keep going

GetType in static method

This is the pattern i used.

abstract class MyBase
{
public static void MyMethod(Type type)
{
doSomethingWith(type);
}
}

How to get the current class' name in a static method?


new StackFrame().GetMethod().DeclaringType

or

MethodBase.GetCurrentMethod().DeclaringType

or

new StackTrace(true).GetFrame(<frame index>).GetMethod() //e.g. <frame index> = 0

c# print the class name from within a static function

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.

Can a static field get the name of the class that its declared in?

this.GetType() should do the trick, if you are not in a static context.

If you are in a static context, use

Type t = MethodBase.GetCurrentMethod().DeclaringType

(from .NET: Determine the type of “this” class in its static method)

How to call static method of a class known only at runtime

There is a misconception in your code:

Delphi has the concept of "class of", which means that a field/variable can keep a reference for the class itself. The .net clr doesn't have this concept. In .Net at runtime you can query for information about a specific type. When you call obj.GetType() you get a Type object containing information about the type. However the Type is not the class itself like in Delphi, it is just a regular object with a bunch of information.

That's why this is illegal in .net:

// TypeOfMyObject is a object of the class Type, which MyObject does not inherit.
(TypeOfMyObject as MyObject).ReturnUsefulStuff();

So, yes, in this case you must use reflection.

var method = typeOfMyObject.GetMethod("ReturnUsefulStuff", 
BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
var result = method.Invoke(null, null);

Get derived class type from a base's class static method

If I'm not mistaken, the code emitted for BaseClass.Ping() and DerivedClass.Ping() is the same, so making the method static without giving it any arguments won't work. Try passing the type as an argument or through a generic type parameter (on which you can enforce an inheritance constraint).

class BaseClass {
static void Ping<T>() where T : BaseClass {
Type t = typeof(T);
}
}

You would call it like this:

BaseClass.Ping<DerivedClass>();


Related Topics



Leave a reply



Submit