#677 – Method Marked with new Modifier Cannot Be Overridden

You can use the new modifier on a method to indicate that the method should hide a method of the same name in a base class.  In other words, the method does not behave polymorphically.

If you’ve marked a method as new in a class, that method is not virtual and can not be overridden in a derived class.

In the example below, the Dog class marks Bark as virtual, indicating that it can be overridden.  The Terrier class marks Bark as new, indicating that it does not override Dog.Bark–and that it cannot be overridden.  JRT can therefore not override Bark.

    public class Dog
    {
        public virtual void Bark()
        {
            Console.WriteLine("  Dog.Bark");
        }
    }

    public class Terrier : Dog
    {
        public new void Bark()
        {
            Console.WriteLine("  Terrier is barking");
        }
    }

    public class JRT : Terrier
    {
        public new void Bark()
        {
            Console.WriteLine("  JRT is barking");
        }
    }

#615 – You Can’t Remove a Base Class Member

A subclass class inherits public members from its base class.  Below, the Terrier class inherits the Name property and the Bark method from the Dog class.

    public class Dog
    {
        public string Name { get; set; }

        public void Bark()
        {
            Console.WriteLine("Woof");
        }
    }

    public class Terrier : Dog
    {
        public string Temperament { get; set; }
    }
            Terrier jack = new Terrier();
            jack.Bark();   // Woof

The Terrier class can provide a new implementation of the Bark method:

    public class Terrier : Dog
    {
        public string Temperament { get; set; }

        public new void Bark()
        {
            Console.WriteLine("Grrr, growf!");
        }
    }

But you can’t completely remove the Bark method from the Terrier class.  If you try making the Bark method in Terrier private, when you invoke the Bark method on a Terrier object, the method in the parent Dog class will be called instead.

#360 – Property Modifiers Required for Polymorphic Behavior

There are three combinations of modifiers that make sense, in determining whether properties in a class are virtual or non-virtual.

Typical combinations of modifiers for base class / derived class (assuming that the property’s name and type are the same in both the base and derived class):

  • (no modifier) / new – Both properties are non-virtual, derived class property hides the base class property
  • virtual / override – Both properties are virtual and support polymorphic behavior
  • virtual / new – Base class property is virtual, derived class property is non-virtual, derived class property hides the base class property

There are two other combinations that are allowed, but result in a compiler warning indicating that you should use new in the derived class to be explicit:

  • (no modifier) / (no modifier) – is equivalent to: (no modifier) / new
  • virtual / (no modifier) – is equivalent to: virtual / new

#359 – The Difference Between Virtual and Non-Virtual Properties

In C#, virtual properties support polymorphism, by using a combination of the virtual and override keywords.  With the virtual keyword on the property in the base class and the override keyword on the property in the derived class, both properties are said to be virtual.

Properties that don’t have either the virtual or override keywords, or that have the new keyword, are said to be non-virtual.

When you read or write a virtual property through an object reference, the run-time type of the object is used to determine which implementation of the property to use.

When you read or write a non-virtual property through an object reference, the compile-time type of the object is used to determine which implementation of the property to use.

#357 – Property in Derived Class Hides Base Class Property by Default

If you define a property in a derived class with the same name and type as a property in the base class, the new property hides the base class property by default.  This is true even if you don’t use the new keyword to explicitly indicate that you intend to hide the property in the base class.

If we have a Dog.Temperament property, the following two code snippets are functionally equivalent.

    public class Terrier : Dog
    {
        public new string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }
        }

 

    public class Terrier : Dog
    {
        // No new keyword, but we're still hiding base class property
        public string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }
        }

Without the new keyword, the compiler warns you that you’re hiding the base class property and recommends using the new keyword.

#356 – Hidden Base Class Property Is Used Based on Declared Type of Object

When you use the new modifier to hide a base class property, its property accessors will still be called by objects whose type is the base class.  Objects whose type is the derived class will use the new property in the derived class.

            Dog kirby = new Dog("Kirby", 15);
            kirby.Temperament = "EAGER";
            Console.WriteLine(kirby.Temperament);  // Kirby is eager

            Terrier jack = new Terrier("Jack", 15);
            jack.Temperament = "CraZY";
            Console.WriteLine(jack.Temperament);  // Terrier Jack is CRAZY

We could also use a variable of type Dog (the base class) to refer to an instance of a Terrier (the derived class).  If we then reference the Temperament property using this base class variable, the Temperament property in the base class is used, even though we’re working with an instance of the derived class.

            Dog kirby = new Dog("Kirby", 15);
            kirby.Temperament = "EAGER";      // Uses Dog.Temperament

            Dog jack = new Terrier("Jack", 15);
            jack.Temperament = "CraZY";       // Also uses Dog.Temperament

#355 – Use the new Keyword to Replace a Property in a Base Class

A derived class inherits data and behavior from its parent class.

There are times when you might want to replace property accessors in a base class with new accessors in the derived class, using the same property name.  You can do this using the new keyword.

Assume a Dog class has a Temperament property:

        protected string temperament;
        public string Temperament
        {
            get
            {
                return string.Format("{0} is {1}", Name, temperament);
            }

            set
            {
                temperament = value.ToLower();
            }
        }

You can provide a new version of this property in a class that derives from Dog, using the new keyword.  This new property hides the property in the base class.

        public new string Temperament
        {
            get
            {
                return string.Format("Terrier {0} is {1}", Name, temperament);
            }

            set
            {
                temperament = value.ToUpper();
            }
        }

The get/set accessors used will now depend on the type of the object.