tags:

views:

128

answers:

2
using System;

namespace random

{

    interface IHelper
    {
        void HelpMeNow();
    }
    public class Base : IHelper
    {
        public void HelpMeNow()
        {
            Console.WriteLine("Base.HelpMeNow()");
        }
    }
    public class Derived : Base
    {
        public new void HelpMeNow()            ///this line
        {
            Console.WriteLine("Derived.HelpMeNow()");
        }
    }
    class Test
    {
        public static void Main()
        {
            Derived der = new Derived();
            der.HelpMeNow();
            IHelper helper = (IHelper)der;
            helper.HelpMeNow();
            Console.ReadLine();
        }
    }
}

the new keyword in the commented line is a little confusing for me. It jsut mean it overrides the implementation of method in base class. Why not use override keyword?

+9  A: 

See this article on MSDN: Knowing When to Use Override and New Keywords

Abtin Forouzandeh
A: 

It's not really overriding it, it's shadowing it. Given a reference to a Derived object, Base's HelpMeNow function will not be accessible1, and derivedObject.HelpMeNow() will call Derived's implementation.

This is not the same as overriding a virtual function, which HelpMeNow is not. If a Derived object is stored in a reference to a Base, or to an IHelper, then Base's HelpMeNow() will be called, and Derived's implementation will be inaccessible.

Derived derivedReference = new Derived();
Base    baseReference    = derivedReference;
IHelper helperReference  = derivedReference;

derivedReference.HelpMeNow(); // outputs "Derived.HelpMeNow()"
baseReference.HelpMeNow();    // outputs "Base.HelpMeNow()"
helperReference.HelpMeNow();  // outputs "Base.HelpMeNow()"

Of course, if the above is not the desired behavior, and it's usually not, there are two possibilities. If you control Base, simply change HelpMeNow() to virtual, and override it in Derived instead of shadowing it. If you don't control Base, then you can at least fix it halfway, by reimplementing IHelper, like so:

class Derived : Base, IHelper{
    public new void HelpMeNow(){Console.WriteLine("Derived.HelpMeNow()");}

    void IHelper.HelpMeNow(){HelpMeNow();}
}

This version of Derived uses what's called explicit interface implementation, which allows you to satisfy the contract of implementing an interface without adding the implementation to your class's public interface. In this example, we already have an implementation in Derived's public interface that's inherited from Base, so we have to explicitly implement IHelper to change it2. In this example, we just forward the implementation of IHelper.HelpMeNow to our public interface, which is the shadow of Base's.

So with this change, a call to baseReference.HelpMeNow() still outputs "Base.HelpMeNow()", but a call to helperReference.HelpMeNow() will now output "Derived.HelpMeNow()". Not as good as changing Base's implementation to virtual, but as good as we're gonna get if we don't control Base.

1Exception: it is accessible from within methods of Derived, but only when qualified with base., as in base.HelpMeNow().
2Notice that we also have to declare IHelper as an interface the class implements, even though we inherit this declaration from Base.

P Daddy
Wow, what a reply. thank you so much. Explained it better than anything I could ever imagine
Tom