21

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
  • 822
  • 1
  • 10
  • 22
  • 1
    Any reason why this particular method is static? – Rad Mar 02 '09 at 17:34
  • The best solution to the problem is rename `Widget.MyMethod`. First think if `Widget.MyMethod` and `Product.MyMethod` are doing the same thing for their name to be the same.. If they are equivalent (means similar thing to user), your're only option is to make them non-static methods.. While I think it would be useful, C# doesnt have the concept of inheritance on static members. Think about now a grandchild class of `FancyWidget`, what should `FancyWidget.MyMethod` call? If you think `Widget.MyMethod` then C# doesnt have a thing for that (nor do any OOP language I think). – nawfal Oct 23 '18 at 05:54

9 Answers9

21

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

}
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • 4
    > 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. – MindModel Mar 02 '09 at 17:36
  • A method that does not rely on an *object* instance does not play by most of the rules defined for objects (virtual method dispatching, ...). – Mehrdad Afshari Mar 02 '09 at 17:38
  • 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 – eglasius Mar 02 '09 at 18:46
  • @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. – Michael Meadows Mar 02 '09 at 19:51
  • 2
    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. – tvanfosson Jan 07 '13 at 14:12
4

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.

Peter Wone
  • 17,965
  • 12
  • 82
  • 134
4

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);
    }
}
marcumka
  • 1,695
  • 3
  • 12
  • 14
3

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

mlipman
  • 356
  • 3
  • 8
2

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.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
1

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:

Community
  • 1
  • 1
Michael Meadows
  • 27,796
  • 4
  • 47
  • 63
0

It's very simple. Much simpler than using aliasing, reflections, etc. Maybe it's been made easier in newer additions of .NET, IDK, but this works perfectly fine. Just like with instance methods, accessing base methods doesn't require base be used, it is optional, usually necessary when the inheriting and base class have a method of the same name. Even without the base keyword, you can access the static methods of a base class as if they were in the class you are calling from. I only tested this when calling a base static method from a derived class's static method. Might not work if you are calling from an instance method to a static method.

public class BaseThings
{
    protected static void AssertPermissions()
    {
        //something
    }
}

public class Person:BaseThings
{
    public static void ValidatePerson(Person person)
    {
        //just call the base static method as if it were in this class.
        AssertPermissions();            
    }
}
AaronLS
  • 37,329
  • 20
  • 143
  • 202
  • 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. – nawfal Dec 16 '13 at 10:46
  • @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. – AaronLS Oct 22 '18 at 13:54
0

Having into account that a Static method shoudn't relay in instance data... you should have a static "MyMethod" that behaves diferent based on a parameter or something like that.

Remember that the static method defined in one class is just a way to order your code... but it is the same if that method is placed elsewhere... because it don't relay on the object where it is placed.

EDIT: I think your best choise is to use Product.MyMethod explicitly... If you think it... it should't be probable that your Widget change its base clase... and also in that case it is a minor change in code.

Romias
  • 13,783
  • 7
  • 56
  • 85
  • 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. – Mehrdad Afshari Mar 02 '09 at 17:36
  • 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? – MindModel Mar 02 '09 at 17:38
  • Well, I should've said that you "Should not" not relay in instance variable data... of course you "CAN". :) – Romias Mar 02 '09 at 18:34
0

Static methods are "Class-Level" methods. They are intended to be methods that apply to all instances of a specific class. Thus, inheritance of this method does not make sense as it would change the meaning to apply to instances of the class. For instance, if you were looping through a collection of Products (some of Widget, some not) and called MyMethod on each Product then the method that was called would be determined by the instance of the class. This violates the purpose of static methods.

You can probably do something like you want more cleanly by simply not using static methods at all, because in your example it does not seem like MyMethod applies to all instances of Product. However, you can achieve the same affect you are describing by using an interface class like ‘IMyMethod’. This approach is still not using a static method. I guess I’m not seeing a need for a static method. Why do you want to use a static method to begin with?

Dunk
  • 1,704
  • 1
  • 14
  • 19