Reputation: 39763
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
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
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
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
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 Figure
s Draw
method will be invoked. No return value is produced, nor expected.
Upvotes: 6