Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call overridden method which have overloads?

I have the following simple code

abstract class A
{
    public abstract void Test(Int32 value);
}

class B : A
{
    public override void Test(Int32 value)
    {
        Console.WriteLine("Int32");
    }

    public void Test(Double value)
    {
        Test((Int32)1);
    }
}

When I ran this code the line Test((Int32)1) causes stack overflow due to infinite recursion. The only possible way to correctly call proper method (with integer parameter) I found is

(this as A).Test(1);

But this is not appropriate for me, because both methods Test are public and I am willing the users to be able to call both method?

like image 604
vharavy Avatar asked Apr 02 '12 17:04

vharavy


People also ask

Can a overridden method be overloaded?

The reason behind this is that the binding of overridden methods is being done at runtime. Private and final methods can be overloaded. Private and final methods can't be overridden.

How do you call an overridden method?

But, since you have overridden the parent method how can you still call it? You can use super. method() to force the parent's method to be called.

How is a call to an overloaded method resolved?

The process of compiler trying to resolve the method call from given overloaded method definitions is called overload resolution. If the compiler can not find the exact match it looks for the closest match by using upcasts only (downcasts are never done). As expected the output is 10.

Is it possible to override an overloaded method in Java?

Yes, we can override overloaded method in Java.


2 Answers

Method overload resolution in C# does not always behave as you might expect, but your code is behaving according to the specification (I wrote a blog post about this a while ago).

In short, the compiler start off by finding methods that

  • Has the same name (in your case Test)
  • are declared in the type (in your case B) or one of its base types
  • are not declared with the override modifier

Note that last point. This is actually logical, since virtual methods are resolved in run-time, not compile time.

Finally, if the type (in this case B) has a method that is a candidate (which means that the parameters in your call can be implicitly converted to the parameter type of the candidate method), that method will be used. Your overridden method is not even part of the decision process.

If you want to call your overridden method, you will need to cast the object to its base type first.

like image 127
Fredrik Mörk Avatar answered Oct 19 '22 20:10

Fredrik Mörk


Unfortunately in order to call the A::Test(int) through a B reference some sort of cast is needed. So long as the C# compiler sees the reference through B it will pick the B::Test(double) version.

A slightly less ugly version is the following

((A)this).Test(1);

Another thought though is have a private method with a different name that both feed into.

class B : A { 
  public override void Test(int i) {
    TestCore(i);
  }
  public void Test(double d) {
    TestCore(1);
  }
  private void TestCore(int i) {
    // Combined logic here
  }
}
like image 4
JaredPar Avatar answered Oct 19 '22 21:10

JaredPar