Can a Static Method Be Overridden in C#

Can a static method be overridden in 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).

C# Override static methods

It's not entirely clear what you are trying to do, but as far as I understand your question, you want to change the behavior of M1(), which is inherited by class Y, by a different static method M2(). This isn't possible, if all methods involved are static, but you can yield the desired effect if you declare M1() as non-static. This might be done this way:

public class X
{
public Boolean M1 (Int32 x1)
{
return M2 (x1);
}
public virtual Boolean M2 (Int32 x2)
{
return M3 (x2);
}
public static Boolean M3 (Int32 x2)
{
return x2 >= 0;
}
}

public class Y : X
{
public override Boolean M2 (Int32 x2)
{
return M3 (x2);
}
public static new Boolean M3 (Int32 x2)
{
return x2 < 0;
}
}

Here's a test case:

Boolean fTest1 = new X ().M1 (1);
Boolean fTest2 = new Y ().M1 (1);

Console.Write ("{0} {1}", fTest1, fTest2);

This will output:

True False

So the wrapper method M2(), which calls the static method M3() in X is virtual and can be overridden in Y, calling a different static method M3(). Hence, if you're using an instance of the derived class Y, the call to M2() inside the inherited method M1() is directed to the M2() method overridden inside Y, which in turn calls the other M3(), with the desired change of behavior - in this example, the result is the inverse boolean value.

Override a static method

Doing the following the will allow you to work around the static call. Where you want to use the code take an IRolesService via dependency injection then when you need MockRolesService you can pass that in.

public interface IRolesService
{
bool IsUserInRole(string username, string rolename);
}

public class RolesService : IRolesService
{
public bool IsUserInRole(string username, string rolename)
{
return Roles.IsUserInRole(username, rolename);
}
}

public class MockRoleService : IRolesService
{
public bool IsUserInRole(string username, string rolename)
{
return true;
}
}

Why is overriding static method alowed in C#

The new keyword does not override a method. It instead creates a new method of the same name which is independent of the original. It is not possible to override a static method because they are not virtual

How to override static, factory-like method in subclasses

Just to elaborate what went on in the comments.

Marking a static method as abstract gives a compile time error. Mainly due to the fact that you cannot apply polymorphism in the general sense to abstract methods (there would never be a virtual method call).

What is needed in this instance is to not mark the method as static. Now the problem that arises from this is that one cannot be sure that one can acquire an instance of T. However, this can be changed by further constraining T to have a constructor taking no arguments, by changing the class definition to:

public abstract class ParametersXml<T> where T : ParametersBase, new()

Now in the catch in LoadOrDefault it is possible to say:

result = new T().CreateDefault();

Notice how this is also a lot cleaner, and avoids both use of reflection and dirty type casts.

EDIT:
Going even further

As pointed out by @AlexeiLevenkov - assuming that CreateDefault is supposed to return an instance of its own type, and that the parameterless constructor is setting up T in its default state. One could even completely remove the need for CreateDefault and simply use the parameterless constructor as CreateDefault, thus changing the line in the catch handler to:

result = new T();


Related Topics



Leave a reply



Submit