Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get derived type from static method

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.

like image 355
Johniak Avatar asked Jan 26 '13 22:01

Johniak


People also ask

Can we access static method derived class?

Hence the answer is 'No'. If a derived class defines a static method with the same signature as a static method in the base class, the method in the derived class is hidden by the method in the base class.

Why static method C#?

A static method in C# is a method that keeps only one copy of the method at the Type level, not the object level. That means, all instances of the class share the same copy of the method and its data. The last updated value of the method is shared among all objects of that Type.

Can we define extension method for static class?

Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter is preceded by the this modifier.

Can static class have a constructor C#?

You can have a static constructor in a static class but you cannot have an instance constructor inside a static class.


2 Answers

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

  1. I wouldn't have to have so much repetitive code and
  2. To ensure all BaseClass objects have 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.

like image 115
David Avatar answered Oct 04 '22 01:10

David


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.

like image 23
SWeko Avatar answered Oct 04 '22 03:10

SWeko