0

Having the following classes, that overrides (or not) the Draw method

using System;

namespace ConsoleApplication1
{
    public class Shape {
        public virtual void Draw() {
            Console.WriteLine("base     Drawing a shape");
        }
    }

    class Rectangle : Shape {
        public new virtual void Draw() {
            Console.WriteLine("new virt Drawing a rectangle");
            base.Draw();
        }
    }
    class Square : Rectangle {
        public override void Draw() {
            Console.WriteLine("new      Drawing a square");
            base.Draw();
        }
    }

    class Triangle : Shape {
        public override void Draw() {
            Console.WriteLine("override Drawing a triangle");
            base.Draw();
        }
    }
    class SuperTriangle : Triangle {
        public new void Draw() {
            Console.WriteLine("new Drawing a SuperTriangle");
            base.Draw();
        }
    }
    class DefaultTriangle : Triangle {
        public void Draw() {
            Console.WriteLine("(-)      Drawing a DefaultTriangle");
            base.Draw();
        }
    }

    class Program {
        static void Main(string[] args) {
            Console.WriteLine(@"
Rectangle       : Shape (new virtual)
Square          : Rectangle (override)

Triangle        : Shape (override)
SuperTriangle   : Triangle (new)
DefaultTriangle : Triangle (-)

");
            System.Collections.Generic.List<Shape> shapes = 
                new System.Collections.Generic.List<Shape>() {
                new Rectangle(), new Square(), 
                new Triangle(), new SuperTriangle(), new DefaultTriangle()};

            foreach (Shape s in shapes) {
                Console.WriteLine();
                Console.WriteLine("(Shape) " + s.GetType().Name);
                Console.WriteLine("________________________");
                s.Draw();
                Console.WriteLine();
            }
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

I have the following output:

Rectangle       : Shape (new virtual)
Square          : Rectangle (override)

Triangle        : Shape (override)
SuperTriangle   : Triangle (new)
DefaultTriangle : Triangle (-)



(Shape) Rectangle
________________________
base     Drawing a shape


(Shape) Square
________________________
base     Drawing a shape


(Shape) Triangle
________________________
override Drawing a triangle
base     Drawing a shape


(Shape) SuperTriangle
________________________
override Drawing a triangle  // <<<< !!!
base     Drawing a shape


(Shape) DefaultTriangle
________________________
override Drawing a triangle  // <<<< !!!
base     Drawing a shape 

Should this mean that the new keyword is not mandatory, but implicitly applied, if no other keyword is specified?

PS. The warning:

Warning 1 'ConsoleApplication1.DefaultTriangle.Draw()' hides inherited member 'ConsoleApplication1.Triangle.Draw()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

serhio
  • 28,010
  • 62
  • 221
  • 374

2 Answers2

2

The code that you have will generate a warning that specifically answers your question.

It tells you that you have not indicated whether the method should be overridden or hides the base class implementation, and that unless otherwise specified, it hides that implementation.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • the warning tells me to add the new keyword. However I had doubts, will this modification add or not changes in the current behavior (without the "new" keyword)... – serhio Mar 25 '14 at 16:13
  • also, for me was not very clear the therm "to hide an implementation", more than that the "new" keyword can be using along with the "override " one... – serhio Mar 25 '14 at 16:16
  • the `new` keyword hides the underlying implementations, meaning any `override` would override the `new virtual` instead of the `virtual` higher up the chain. Like a break point sort of. – Haney Mar 25 '14 at 16:20
  • Thanks David and Servy. The question, however, was if the explicit `new` is equivalent to just not specifying any keyword before the function name. – serhio Mar 25 '14 at 16:28
0

The warning explicitly tells the actual behavior:

'method' hides inherited member 'base method'

So yes, the new behavior is the default one. If you want to know a reasoning behind it, or to get more details about the whole question - please refer to great answer by @EricLippert in this thread.

Community
  • 1
  • 1
Andrei
  • 55,890
  • 9
  • 87
  • 108