Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 478
MindModel Avatar asked Mar 02 '09 17:03

MindModel


6 Answers

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();  }

}
like image 177
mmx Avatar answered Sep 21 '22 08:09

mmx


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);
    }
}
like image 30
marcumka Avatar answered Sep 24 '22 08:09

marcumka


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.

like image 40
Peter Wone Avatar answered Sep 24 '22 08:09

Peter Wone


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).

like image 34
mlipman Avatar answered Sep 23 '22 08:09

mlipman


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.

like image 20
tvanfosson Avatar answered Sep 25 '22 08:09

tvanfosson


Static methods are not polymorphic, so what you want to do is impossible.

Trying to find a way to treat static methods as polymorphic is possible but dangerous, because the language itself doesn't support it.

Some suggestions:

  • Reflection
  • Aliasing the base class (such as Mehrdad's example)
like image 32
Michael Meadows Avatar answered Sep 21 '22 08:09

Michael Meadows