Can a static method be overridden in C#?

73,141

Solution 1

(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

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

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)
Share:
73,141

Related videos on Youtube

aspiring
Author by

aspiring

C# <----asp.net, jscript for now.

Updated on July 09, 2022

Comments

  • aspiring
    aspiring almost 2 years

    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?

    • Alex Filipovici
      Alex Filipovici over 11 years
      No, they can't be overridden. They are associated with the class, not with an object.
    • Najzero
      Najzero over 11 years
      for the real use: you can call a static method without the class instance.
    • aspiring
      aspiring over 11 years
      Thanks. I understand what a static method is, best example given by SLaks. So for my question about overriding a static method (if bydefault is it final, not user make it final) - does it mean no subclass of this class which holds a static can define a static method with the same signature?
    • Neel
      Neel over 11 years
      btw it seems like a question asked in my exam paper :P
    • aspiring
      aspiring over 11 years
      I don't think you are my class mate :D but happy to be. PS: If notice the novice flavour of my question, yes I am in the phase of learning proper theory - I realized without them I can only write algo-codes but not able to properly explain :)
    • Alex
      Alex over 11 years
      The compiler itself could have tol you that static members cannot be marked as virtual, override or abstract
    • John
      John over 11 years
      Maybe the best way to understand best usage is to look at how Microsoft has used them in the .Net Framework. Here's a link to MSDN API's on System.String. msdn.microsoft.com/en-us/library/system.string.aspx Notice the methods with red S, this indicates the method is static. Operator overloads are always done as static methods.
  • aspiring
    aspiring over 11 years
    I have no issues with instance methods. I learnt that static Class can't be instantiated. But you mentioned that "static methods is that it is instantiated only once in your app".. So I am confused now. Are you referring to Using System.Math; by saying static methods are instantiated? I have been using Math class members Math.Abs() multiple times in the same class without instantiating them even once. 1) So could you please clarify what you meant by "instantiating once"? 2) Can a Static Class be sub-classes? Does it make sense to Sub-Class a static class?
  • aspiring
    aspiring over 11 years
    Thanks. It's slightly bit up level for me to digest, but along the way I will get it :) PS: And I definitely want to be in your class in that case. Found this post too in Java context.
  • Thiago Silva
    Thiago Silva over 11 years
    see my edit. I shouldnt have used the term "instantiated" with a static method. more correct is to say that it is only created once.
  • Matthew Watson
    Matthew Watson over 11 years
    All methods are only "created" once. Even non-static methods have only one copy of the code in existence (IL code which is created at compile-time and converted into machine code once at run-time). Do not confuse code and data! A non-static method is only callable via an instance of an object, but that is because of the hidden "this" pointer which is passed to it. The code itself is "static" in that it's fixed and singleton.
  • Thiago Silva
    Thiago Silva over 11 years
    @MatthewWatson thanks for the correction. I removed the offending section and updated answer
  • aspiring
    aspiring over 11 years
    Thanks for giving me that example of overriding. Yes I am trying out in the code. So to get this right, 1) we can sub-class a static class like any other non-static class? 2) we can use static methods without overriding parent class static methods but hiding them using New keyword.
  • atlaste
    atlaste over 11 years
    I added some more explanation and an example. (1) No you cannot sub-class a static class, but you can hide static members. (2) yes, you should try the second example, it tells how it behaves.
  • Mickey Perlstein
    Mickey Perlstein over 9 years
    when will this Foo<-> Bar nonsense end??? stop using FoorBar for examples, in each case Bar and Foo are either classes or subclasses or functions or methods. so whats the point ??? just use Animals for subclassing and actions for overriding. 10x
  • Black
    Black over 6 years
    I get: 'Bar' member names cannot be the same as their enclosing types if I apply your first example. Bar.Bar can't even work.