Reputation: 991
I want to get derived type from static method.
I want to do something like this
void foo()
{
this.getType();
}
but in static method
I know that
MethodBase.GetCurrentMethod().DeclaringType
returns base type, but i need derived.
Upvotes: 13
Views: 4494
Reputation: 42991
As you alluded to in a comment, it is possible using generics. Running this - say in LinqPad - will produce 'MyDerivedClass'.
void Main()
{
MyDerivedClass.DoSomething();
}
abstract class MyBaseClass<T> where T : MyBaseClass<T>
{
public static void DoSomething()
{
Console.WriteLine(typeof(T).Name);
}
}
class MyDerivedClass : MyBaseClass<MyDerivedClass>
{
}
Upvotes: 0
Reputation: 4953
7 1/2 years later...
I was wanting to do very much the same thing which is how I found this question. There is a solution that is close to what is being asked for and MAY be useful for others searching this question.
I wanted a static method that would return an instance of the class with all the base settings set for me. The following works:
void Main()
{
ChildClassA cA = ChildClassA.SetFoo();
}
public abstract class BaseClass
{
public bool Foo {get; set;}
}
public class ChildClassA : BaseClass
{
public static ChildClassA SetFoo() => new ChildClassA{Foo = false};
}
public class ChildClassB : BaseClass
{
public static ChildClassB SetFoo() => new ChildClassB { Foo = false };
}
That's all well and good, but I wanted to put that SetFoo
function in the base class so that
SetFoo
.You cannot do:
public abstract static BaseClass SetFoo;
because something that is static cannot be abstract. You also cannot do:
public static BaseClass SetFoo => new BaseClass{ Foo = false };
because you can't new up an abstract class.
What you CAN do, though, is use generics to specify the derived type you want. That would look like this:
void Main()
{
ChildClassA cA = BaseClass.SetFoo<ChildClassA>();
}
public abstract class BaseClass
{
public bool Foo {get; set;}
public static T SetFoo<T>() where T:BaseClass, new() => new T{Foo = false };
}
public class ChildClassA : BaseClass
{
// You can leave this here if you still want to call ChildClassA.SetFoo();
//public static ChildClassA SetFoo() => new ChildClassA{Foo = false};
}
public class ChildClassB : BaseClass
{
//Again, you can leave this for ChildClassB.SetFoo()--the compiler won't mind
//public static ChildClassB SetFoo() => new ChildClassB { Foo = false };
}
This is only a little more clunky than what we really wanted (derived.StaticBase), but it's pretty close.
Upvotes: 2
Reputation: 30872
I guess you need something like this scenario:
void Main()
{
Base.StaticMethod(); // should return "Base"
Derived.StaticMethod(); // should return "Derived"
}
class Base
{
public static void StaticMethod()
{
Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
}
}
class Derived: Base
{
}
This code will, however, return
Base
Base
This is due to the fact that the static method call is resolved at compile time as a call to the base class, that actually defines it, even if it was called from a derived class. The lines
Base.StaticMethod();
Derived.StaticMethod();
generates the following IL:
IL_0001: call Base.StaticMethod
IL_0006: nop
IL_0007: call Base.StaticMethod
In a word, it cannot be done.
Upvotes: 12
Reputation: 217233
Assuming you mean you have something like this
class MyBaseClass
{
public static void DoSomething()
{
Console.WriteLine(/* current class name */);
}
}
class MyDerivedClass : MyBaseClass
{
}
and want MyDerivedClass.DoSomething();
to print "MyDerivedClass"
, then the answer is:
There is no solution to your problem. Static methods are not inherited like instance methods. You can refer to DoSomething
using MyBaseClass.DoSomething
or MyDerivedClass.DoSomething
, but both are compiled as calls to MyBaseClass.DoSomething
. It is not possible to find out which was used in the source code to make the call.
Upvotes: 16