C#: How do I call a static method of a base class from a static method of a derived class?

42,628

Solution 1

static methods are basically a method to fallback from object oriented concepts. As a consequence, they are not very flexible in inheritance hierarchies and it's not possible to do such a thing directly.

The closest thing I can think of is a using directive.

using mybaseclass = Namespace.BaseClass;

class MyClass : mybaseclass {

  static void MyMethod() {  mybaseclass.BaseStaticMethod();  }

}

Solution 2

It can be done, but I don't recommend it.

public class Parent1
{
    public static void Foo()
    {
        Console.WriteLine("Parent1");
    }
}

public class Child : Parent1
{
    public new static void Foo()
    {
        Type parent = typeof(Child).BaseType;
        MethodInfo[] methods = parent.GetMethods();
        MethodInfo foo = methods.First(m => m.Name == "Foo");
        foo.Invoke(null, null);
    }
}

Solution 3

Calling a static method using reflection is exactly the same as calling an instance method except that you pass null for the instance. You need FlattenHierarchy because it's defined in an ancestor.

var type = assy.GetType("MyNamespace.MyType");
MethodInfo mi = type.GetMethod("MyStaticMethod", 
  BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
mi.Invoke(null, null);

Further reading and thinking leaves me asking the same questions as others who have responded: why use static methods like this? Are you trying to do functional programming, and if so why not use lambda expressions instead? If you want polymophic behaviours with shared state, instance methods would be better.

Solution 4

It can be done:

public class Parent1
{
    protected static void Foo()
    {
        Console.WriteLine("Parent1");
    }
}

public class Child : Parent1
{
    public static void Foo()
    {
        return Parent1.Foo();
    }
}

Can be useful for unit testing protected static methods (for example).

Solution 5

First and foremost, if you're worried about re-parenting a class, then you're probably doing inheritance wrong. Inheritance should be used to establish "is-a" relationships, not simply foster code reuse. If you need code re-use alone, consider using delegation, rather than inheritance. I suppose you could introduce an intermediate type between a sub-type and its parent, but I would let that possibility drive my design.

Second, if you need to use functionality from the base class but extend it AND the use case calls for a static method, then you might want to consider using some external class to hold the functionality. The classic case for this in my mind is the Factory pattern. One way to implement the Factory pattern is through Factory Methods, a static method on a class that constructs an instance of that class. Usually the constructor is protected so that the factory method is the only way to build the class from outside.

One way to approach re-use with Factory Methods in an inheritance hierarchy would be to put the common code in a protected method and call that method from the Factory Method rather than directly call the base class Factory Method from a sub-types Factory Method. A better implementation might use the same technique but move the Factory Methods to a Factory class and use the constructor logic (internal now, not private), perhaps in conjunction with an initialization method(s), to create the object. If the behavior you are inheriting is external from the class (decryption/validation/etc), you can use shared methods (or composition) within the Factory to allow re-use between the Factory methods.

Without knowing the goal of your use of static methods it's difficult to give you an exact direction, but hopefully this will help.

Share:
42,628
MindModel
Author by

MindModel

Updated on July 09, 2022

Comments

  • MindModel
    MindModel almost 2 years

    In C#, I have base class Product and derived class Widget.

    Product contains a static method MyMethod().

    I want to call static method Product.MyMethod() from static method Widget.MyMethod().

    I can't use the base keyword, because that only works with instance methods.

    I can call Product.MyMethod() explicitly, but if I later change Widget to derive from another class, I have to revise the method.

    Is there some syntax in C# similar to base that allows me to call a static method from a base class from a static method of a derived class?

  • MindModel
    MindModel about 15 years
    > static methods are basically a method to fallback... Why is this true? In the code for my class, the methods that rely on instance data are instance methods. The methods that don't rely on instance data, but only rely on parameters (if any) are static methods. I find this distinction useful.
  • mmx
    mmx about 15 years
    Not completely true. static methods can rely on private members of a type (both static and instance), as a result, they are not completely movable.
  • MindModel
    MindModel about 15 years
    True. You know the difference between static variables (one per class) and instance variables (one per instance). Why is this distinction not useful? Why it is bad OO design?
  • mmx
    mmx about 15 years
    A method that does not rely on an object instance does not play by most of the rules defined for objects (virtual method dispatching, ...).
  • MindModel
    MindModel about 15 years
    Fair enough. In this case, the solution is worse than the problem. Thanks.
  • Romias
    Romias about 15 years
    Well, I should've said that you "Should not" not relay in instance variable data... of course you "CAN". :)
  • eglasius
    eglasius about 15 years
    mindmodel, while there are some scenarios for it, if you start needing inheritance or [insert any other restriction vs. non static methods] it is a symptom that something else might be off ... perhaps the class have too many responsibilities
  • Michael Meadows
    Michael Meadows about 15 years
    @Freddy, my sentiments exactly. Almost always when you're trying to do something the language doesn't support, then you're either using the wrong language, or trying to put a square peg in a round hole. Ruby would get @mindmodel closer to what he wants since classes are objects.
  • Sergey Mirvoda
    Sergey Mirvoda almost 15 years
    nstead of using string you could use MethodBase.GetCurrentMethod().Name
  • tvanfosson
    tvanfosson over 11 years
    I disagree that static methods aren't object-oriented. They may be used this way frequently but, as the saying goes "you can write Fortran in any language." At worst, the concepts are orthogonal. See my answer for a classic case where static methods are directly used to support an object-oriented paradigm, the Factory pattern.
  • nawfal
    nawfal over 10 years
    Aaron, OP has the same method name for base and derived classes. Along with the fact that she doesn't want to specify Base.StaticMethod explicitly, these two are the crux of the problem.
  • AaronLS
    AaronLS over 5 years
    @nawfal Yeh looks like no where did they say "from static method of the same name". That would have been a better title. I do see they mentioned from static method Widget.MyMethod(). which happens to be the same name as the base method. This is where code example makes things clearer. I would have just used their example to solution. I'll leave my answer as is since this comes up in google with an applicable to the title of the question for calling a base class static method.