1

I have the following classes and methods

public class X
{
    public static void M1(...)
    {
        ...
        var isSomething = M2(...);
        ...
    }

    public static bool M2(...) { ... }
}

I need to implement a new M2 method with same signature to be called in some ocasions. To do this I was thinking to implement a new class Y extending X and override M2 method, so when I call Y.M1() I want to use y.M2().

public class Y : X
{
    public static [override] bool M2(...) { ... }
}

But static methods cannot be overriden. Anyone has an advice how could I can do this?

cesarfaria
  • 83
  • 1
  • 8
  • 4
    It's kind of funny that you chose `X` and `Y` as your example class names because this is potentially an [XY problem](https://meta.stackexchange.com/a/66378). Can you give us a little more context about what you are trying to do and *why* you want to do it this way? – Lews Therin Mar 21 '19 at 18:47
  • 1
    That indeed sounds like you **actually** need something completely different, but just **assume** overriding a static method would be the solution. But without any further information about why you need this it´s hard to guess. Why not just make some condition and call either one method or the other one? – MakePeaceGreatAgain Mar 21 '19 at 18:48
  • @cesarfaria Is `M2()` really required to be static? If not, just remove the `static` modifier. As long as this method doesn't need to be callable from other classes without a reference to an instance of `class X`, this is always possible. Otherwise, create a `virtual` wrapper for `M2()` and call it from `M1()`. Then override this one with a method that calls the other `M2()`. – SBS Mar 21 '19 at 18:55

2 Answers2

3

Static methods cannot be overridden. Dynamic binding is possible only with object instances.

You can "hide" static methods from base class with new keyword as explained here. In your case, you can write your Y.M2() with following style:

public class Y : X
{
    public static new bool M2(...) { ... }
}

Keep in mind that this style is not same as normal virtual non-static method overriding. With non-static method overriding, method binding is done run-time depending on actual object type. static-method binding is done in compile-time.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Risto M
  • 2,919
  • 1
  • 14
  • 27
  • 2
    The `new` keyword just gets rid of the warning that hiding an inherited member might not be intended. It doesn't solve the problem stated in the question, however - that is, calling `Y.M1()` will still call `X.M2()`, and not `Y.M2()`, because hiding is not the same as overriding. – SBS Mar 21 '19 at 20:53
2

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.

SBS
  • 806
  • 5
  • 13
  • 2
    Thanks, I was thinking that I could use only static methods to do that, like Risto M sugested in previous answer, but is not working. – cesarfaria Mar 22 '19 at 10:07
  • 2
    @cesarfaria Yes, the problem here is that static methods can be hidden, but not overridden. That's two different things. You need an override to get the call directed to the inherited class, and hence a virtual method must be involved somewhere. Frankly, I had a similar problem myself not long ago, and wished that I could override a static method. – SBS Mar 22 '19 at 10:23