The new Modifier

The new modifier hides the specified member of the base class. The new modifier is the default modifier when a member is repeated (with the same signature) in the derived type. However, unless the new keyword is enunciated, a compiler warning is presented to prevent the accidental hiding of a member of the base class. Explicit use of the new keyword avoids the warning. A virtual member and override member are related, which is important to polymorphism. The derived member with the new modifier and the base member are unrelated.

.NET supports hide-by-signature and hide-by-name techniques. C# supports only hide-by-signature, where a single member is hidden using the new modifier. Hide-by-name hides the entire interface of a member, which may entail several functions. This feature is available in Visual Basic .NET.

In the following code, ZClass is the base class and contains MethodA and MethodB members. Both are virtual methods, where MethodB calls MethodA:

public virtual void MethodB() {
    MethodA();
}

YClass is a derived class and inherits from ZClass. MethodA is overridden in the derived type, but MethodB is not overridden. Therefore, two versions of MethodA exist: a base version and a derived version. When YClass.MethodB is called, which version of MethodA is invoked in the method? Because MethodA is virtual, the most derived method is called. YClass.MethodA is invoked. With a virtual method, the compiler prefers the most derived method.

Here is the code:

using System;

namespace Donis.CSharpBook {

    public class Starter {
        public static void Main() {
            YClass obj = new YClass();
            obj.MethodB();  // Writes YClass.MethodA
        }
    }

    public class ZClass {
        public virtual void MethodA() {
             Console.WriteLine("ZClass.MethodA");
        }

        public virtual void MethodB() {
             MethodA();
        }
    }

    public class YClass : ZClass
    {
        public override void MethodA() {
             Console.WriteLine("YClass.MethodA");
        }
    }
}

The following code is almost identical to the previous code. However, ZClass.MethodA is not overridden in the derived class. The new modifier defines a new MethodA in the derived class that is unrelated to MethodA of the base class. Because ZClass.MethodA and YClass.MethodA now are unrelated, methods inherited from a base class cannot call the derived MethodA implicitly. Instead, the nearest related method in an ascendant class is called. In the example, the nearest related MethodA is in the base class. Therefore, the compiler will not delegate to YClass.MethodA. For this reason, YClass.MethodB calls ZClass.MethodA. This prevents functions inherited by the derived class from calling unrelated functions, which could cause the fragile base class problem:

using System;

namespace Donis.CSharpBook {

    public class Starter {
        public static void Main() {
            YClass obj = new YClass();
            obj.MethodB();  // Writes ZClass.MethodA
        }
    }

    class ZClass {
        public virtual void MethodA() {
             Console.WriteLine("ZClass.MethodA");
        }

        public virtual void MethodB() {
             MethodA();
        }
    }

    class YClass : ZClass {
        public new void MethodA() {
             Console.WriteLine("YClass.MethodA");
        }
    }
}

Interestingly, although the new modifier hides the base class member, you still can access the base class implementation with the base keyword (shown in bold type in the following code). This is demonstrated here:

public class ZClass {
     public virtual void MethodA() {
         Console.WriteLine("ZClass.MethodA");
    }
}

public class YClass : ZClass
{
    public new void MethodA() {
         base.MethodA();
         Console.WriteLine("YClass.MethodA");
    }
}

Virtual methods are overridable in all descendants. However, the new modifier stops the method from being virtual at that point in the hierarchy. The new modifier means the derived member replaces the base member in its entirety—this includes any modifiers. A method can be declared with both new and virtual modifiers. In that circumstance, the method hides the base method and the replacement method is also virtual.

The following code demonstrates that a member with the new modifier, but without the virtual modifier, cannot be overridden. The virtual modifier of the base class does not extend to the same method with the new modifier.

public class ZClass {
    public virtual void MethodA() {
    }

    public virtual void MethodB() {
    }
}

public class YClass : ZClass {
    public new virtual void MethodA() {
    }

    public new void MethodB() {
    }
}

public class XClass : YClass {
    public override void MethodA() {
    }

    /*  ERROR

    public override void MethodB() {
    }
    */
}

In the preceding code, XClass.MethodB causes a compiler error. XClass inherits from YClass. In YClass, MethodB is replaced but not tagged with the virtual modifier. Therefore, XClass.MethodB cannot override YClass.MethodB. XClass.MethodA can override YClass.MethodA because YClass.MethodA has both the new and virtual modifiers.

Data members or static members in a base class cannot be overridden in a derived class. However, both can be hidden with the new modifier. Hiding data members and static members can cause confusion. When you use this feature, thoroughly document your code.

In the following code, ZClass has a static method and a static field. Their purpose is to count ZClass instances. YClass inherits ZClass and hides the two static members of the base type. The new members count the instances of YClass. Therefore, there are simultaneous counts—the base class and derived class counters. In Main, multiple instances of ZClass and YClass are created. Both counters are then displayed:

using System;

namespace Donis.CSharpBook {
    public class Starter {
        public static void Main() {
            ZClass obj1 = new ZClass();
            YClass obj2 = new YClass();
            YClass obj3 = new YClass();
            ZClass.DisplayCounter();
            YClass.DisplayCounter();
        }
    }

    public class ZClass {
        public ZClass() {
            ++count;
        }

        public static int count = 0;
        public static void DisplayCounter() {
             Console.WriteLine("ZClass.Count:");
             Console.WriteLine(count);
        }
    }

    public class YClass : ZClass
    {
        public YClass() {
            ++count;
        }

        private new static int count = 0;

        public new static void DisplayCounter() {
             Console.WriteLine("YClass count:");
             Console.WriteLine(count);
        }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.144.56