Can a static method be overridden in C#?

C#OverridingStatic MethodsFinal

C# Problem Overview


I was told that static methods are implicitly final and therefore can't be overridden. Is that true?

  1. Can someone give a better example of overriding a static method?

  2. If static methods are just class methods, what is the real use of having them?

C# Solutions


Solution 1 - C#

(1) Static methods cannot be overridden, they can however be hidden using the 'new' keyword. Mostly overriding methods means you reference a base type and want to call a derived method. Since static's are part of the type and aren't subject to vtable lookups that doesn't make sense.

E.g. statics cannot do:

public class Foo { 
    public virtual void Bar() { ... }
}
public class Bar : Foo {
    public override void Bar() { ... }
}

// use:
Foo foo = new Bar(); // make an instance
foo.Bar(); // calls Bar::Bar

Because statics don't work on instances, you always specify Foo.Bar or Bar.Bar explicitly. So overriding has no meaning here (try expressing it in code...).

(2) There are different usages for static methods. For example, it's being used in the Singleton pattern to get a single instance of a type. Another example is 'static void Main', which is the main access point in your program.

Basically you use them whenever you don't want or cannot create an object instance before using it. For example, when the static method creates the object.

[update]

A simple hiding example:

public class StaticTest
{
    public static void Foo() { Console.WriteLine("Foo 1"); }
    public static void Bar() { Console.WriteLine("Bar 1"); }
}

public class StaticTest2 : StaticTest
{
    public new static void Foo() { Console.WriteLine("Foo 2"); }
    public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1
}

public class TestStatic
{
    static void Main(string[] args)
    {
        StaticTest2.Foo();
        StaticTest2.Some();
        StaticTest.Foo();
        Console.ReadLine();
    }
}

Note that if you make the classes static, you cannot do this. Static classes have to derive from object.

The main difference between this and inheritance is that the compiler can determine at compile-time which method to call when using static. If you have instances of objects, you need to do this at runtime (which is called a vtable lookup).

Solution 2 - C#

Well You can't override a static method. A static method can't be virtual, since it's not related to an instance of the class.

The "overridden" method in the derived class is actually a new method, unrelated to the one defined in the base class (hence the new keyword).

This is an important thing to understand: when types inherit from other types, they fulfil a common contract, whereas static types are not bound by any contract (from the pure OOP point of view). There's no technical way in the language to tie two static types together with an "inheritance" contract. If you would "override" the Log method in two different places.

If you think about overriding static methods it, it doesn't really make sense; in order to have virtual dispatch you need an actual instance of an object to check against.

A static method also can't implement an interface; if this class is implementing an IRolesService interface then I would contend that the method should not be static at all. It's better design to have an instance method, so you can swap out your MockRoleService with a real service when you're ready

Solution 3 - C#

You don't override a static method. You hide it. See this answer for more info.

Some reasons to use static methods:

  1. They are a little bit faster than instance methods. Also see this msdn article which gives performance numbers to back this up (inlined static call avg 0.2 ns, static call avg 6.1ns, inlined instance call avg 1.1 ns, instance call avg 6.8 ns)
  2. Less verbose to write out - don't need to instantiate a class to get to them (and instantiation can also affect performance)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaspiringView Question on Stackoverflow
Solution 1 - C#atlasteView Answer on Stackoverflow
Solution 2 - C#NeelView Answer on Stackoverflow
Solution 3 - C#Yaakov EllisView Answer on Stackoverflow