Konerak
Konerak

Reputation: 39763

Different return type for same method of a base class

A very simple base class:

class Figure {
    public virtual void Draw() {
        Console.WriteLine("Drawing Figure");
    }
}

This inheriting class:

class Rectangle : Figure
{
    public int Draw()
    {
        Console.WriteLine("Drawing Rectangle");
        return 42;
    }
}

The compiler will complain that Rectangle's "Draw" hides the Figure's Draw, and asks me to add either a new or override keyword. Just adding new solves this:

class Rectangle : Figure
{
    new public int Draw() //added new
    {
        Console.WriteLine("Drawing Rectangle");
        return 42;
    }
}

However, Figure.Draw has a void return type, Rectangle.Draw returns an int. I am surprised different return types are allowed here... Why is that?

Upvotes: 4

Views: 3144

Answers (4)

Sergej Christoforov
Sergej Christoforov

Reputation: 1606

The new keyword just tells the compiler that this method is not overriding the base one, but just has the same name. It will not be executed by a virtual call from base class.

class Base 
{
    public virtual void A()
    {
        Console.WriteLine("Base::A");
    }
    public virtual void B()
    {
        Console.WriteLine("Base::B");
    }
}

class Derived : Base 
{
    public override void A()
    {
        Console.WriteLine("Derived::A");
    }
    public new int B()
    {
        Console.WriteLine("Derived::B");
    }
}

So,

Base obj = new Derived();
obj.A();
obj.B();

will output

Derived::A
Base::B

Upvotes: 4

Tejs
Tejs

Reputation: 41236

What is happening here is that you are hiding the base element's method. So effectively, the Draw method in Rectangle is a new method, as though the name was something else.

If you consume this element when the type is Rectangle, it will know the return type, but if you attempt to use this instance boxed into the base type, the base method will be called with a void return type.

Upvotes: 4

Amy B
Amy B

Reputation: 110071

With the "new" keyword, you can only call the int Draw from a Rectangle reference. There is no runtime method resolution.

Rectangle r = new Rectangle();
Figure f = r;
f.Draw();  // calls the void method Figure.Draw
int x = r.Draw(); // calls the int method Rectangle.Draw

Upvotes: 2

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239646

Did you actually read up on the new modifier?

Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.

So, you've hidden the version from the base class. The fact that these two methods have the same name doesn't mean anything - they're no more related than two methods whose names sound the same.


Such a situation should generally be avoided, but the compiler will always know which method is to be called, and thus whether it has a return value or not. If "the" method is accessed as follows:

Figure r = new Rectangle();
r.Draw();

Then Figures Draw method will be invoked. No return value is produced, nor expected.

Upvotes: 6

Related Questions