1

In the following I would like a call to MyOtherClass.MyStaticMethod() to output "MyOtherClass", is this possible? All my current attempts give me "MyClass".

The issue I have is that I can't easily change MyOtherClass, since there are 100s of classes which extend from MyClass.

public class MyClass
{
    public static string MyStaticMethod()
    {
        string className = typeof(MyClass).Name;
        Console.WriteLine(className);
    }
}
public class MyOtherClass : MyClass{ }
  • You can abuse generics to get this. I don't recommend it. Link: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/1cb74fe7-dfc8-45c0-8ad4-34e4c6e990c9 – Hans Passant Feb 19 '10 at 12:44

4 Answers4

1

Don't you need it to be an instance method, then call

string className = typeof(this).Name;
Paul Manzotti
  • 5,107
  • 21
  • 27
1

In C# and Java you can overload a static method, but not override it. That is, polymorphism and inheritance on static method does not exists. (See this question for more detail)

There is not concept of this on static method, and as a consequence, you can not get the type in a polymorphic way. Which means that you would need to define one static method per class in a way to print the right type.

Community
  • 1
  • 1
ewernli
  • 38,045
  • 5
  • 92
  • 123
1

This is somewhat related to a question I just asked last week: C# static member “inheritance” - why does this exist at all?.

To cut to the chase, C# doesn't really support static method inheritance - so, you can't do what you ask. Unfortunately, it is possible to write MyOtherClass.MyStaticMethod() - but that doesn't mean there's any real inheritance going on: under the covers this is just the scoping rules being very lenient.

Edit: Although you can't do this directly, you can do what C++ programmers call a Curiously Recurring Template Pattern and get pretty close with generics[1]:

public class MyClass<TDerived> where TDerived:MyClass<TDerived> {
    public static string MyStaticMethod() { return  typeof(TDerived).Name; }
}
public class MyOtherClass : MyClass<MyOtherClass> { }
public class HmmClass:MyOtherClass { }

void Main() {
    MyOtherClass.MyStaticMethod().Dump(); //linqpad says MyOtherClass
    HmmClass.MyStaticMethod().Dump();  //linqpad also says MyOtherClass
}

Here, you do need to update the subclass - but only in a minor fashion.

Community
  • 1
  • 1
Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
  • However, this is a major code change as the OP specifies that there are "are 100s of classes which extend from MyClass". – AxelEckenberger Feb 19 '10 at 11:42
  • Yep, but it's simpler than any other alternative I could come up with - and the compiler can help you here, as adding the generic type parameter will mean that any non-generic reference to MyClass will be invalid. I've done this kind of refactoring before (for probably more than a 1000 references) - it's mind-numbing F8 for next error, go fix, etc, but it's just a days work, at worst. – Eamon Nerbonne Feb 19 '10 at 12:00
  • And in this case, a regex might actually automatically fix all compile errors; simply replace `^{.*class {.*}.* : .* }MyClass{.*}$` with `\1MyClass<\2>\3` in VS.NET's wonky syntax (or some similar such search). – Eamon Nerbonne Feb 19 '10 at 12:03
0

Starting from version 3.5 of the .NET framework you could use an extension function to retrieve the information about the instance of the class.

public static class MyClassExtensions {
  public static string Name(this MyClass instance) {
    return typeof(instance).Name;
  }
}

Provides an instance method without modifying the definition of MyOtherClass.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70