views:

690

answers:

4

Can anyone explain the actual use of method hiding in C# with a valid example ?

If the method is defined using the new keyword in the derived class, then it cannot be overridden. Then it is the same as creating a fresh method (other than the one mentioned in the base class) with a different name.

Is there any specific reason to use the new keyword?

+5  A: 

C# not only supports method overriding, but also method hiding. Simply put, if a method is not overriding the derived method, it is hiding it. A hiding method has to be declared using the new keyword. The correct class definition in the second listing is thus:

    using System;
    namespace Polymorphism
    {
        class A
        {
            public void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A
        {
            public new void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // output --> "A::Foo()"
                b.Foo();  // output --> "B::Foo()"

                a = new B();
                a.Foo();  // output --> "A::Foo()"
            }
        }
    }
ArsenMkrt
I guess the same can be acheived without the new keyword, only thing is the compiler gives a warning . otherwise does it have any significant difference.?
vijaysylvester
no, there is no difference, compiler gives a warning and it works as you wrote new keyword if you don't pay attention to warning
ArsenMkrt
The important thing here is that the type of the reference determines the method called.
Anderson Imes
Complete article can be found at http://www.akadia.com/services/dotnet_polymorphism.html
Groo
A: 

The new declaration may be any type of enity. It (new) specifies that the class hide an inherited member by the same name. A new modifier does not remove the inherited type members but that name unavailable in the dereived class.

adatapost
+7  A: 

One use I sometimes have for the new keyword is for 'poor mans property covariance' in a parallell inheritance tree. Consider this example:

public interface IDependency
{
}

public interface ConcreteDependency1 : IDependency
{
}

public class Base
{
  protected Base(IDependency dependency)
  {
    MyDependency = dependency;
  }

  protected IDependency MyDependency {get; private set;}
}

public class Derived1 : Base // Derived1 depends on ConcreteDependency1
{
  public Derived1(ConcreteDependency1 dependency)  : base(dependency) {}

  // the new keyword allows to define a property in the derived class
  // that casts the base type to the correct concrete type
  private new ConcreteDependency1 MyDependency {get {return (ConcreteDependency1)base.MyDependency;}}
}

The inheritance tree Derived1 : Base has a 'parallell dependency' on ConcreteDependency1 : IDependency'. In the derived class, I know that MyDependency is of type ConcreteDependency1, therefore I can hide the property getter from the base class using the new keyword.

EDIT: see also this blog post by Eric Lippert for a good explanation of the new keyword.

jeroenh
interesting -> +1
Juri
That was really good dude . i was not aware of those intricacies
vijaysylvester
Agreed, +1 for informative and useful example.
shambulator
+7  A: 

I think ArsenMkrt's example is not fully correct, at least it does not fully explain the hiding feature. By dropping the new keyword from the Foo method in class B, you will still get the output

A::Foo()
B::Foo()
A::Foo()

In a programming language like Java, where all methods are "virtual", you'd expect to get the output

A::Foo()
B::Foo()
B::Foo()

by taking ArsenMkrt's code above, due to the instantiation

A a;
B b;

a = new A();
b = new B();
a.Foo(); 
b.Foo(); 

a = new B(); //<< Here
a.Foo();

In his example however, you still get "A::Foo()" because in C# methods aren't virtual by default and so the method B::Foo() automatically hides A's Foo(). To achieve the polymorphic behavior one has to write it as follows instead:

class A
{
    public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}

class B : A
{
    public override void Foo() { Console.WriteLine("B::Foo()"); }
}

Now is where the "new" keyword comes in. Actually when you leave the "override" from B::Foo(), then you again would hide A::Foo() meaning that you don't override it's default behavior and you don't achieve polymorphism, i.e. you get "A::Foo()" again as output. The same can be achieved - and here's where I don't 100% understand why you HAVE to put it - by placing the "new" keyword like..

class A
{
    public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}

class B : A
{
    public new void Foo() { Console.WriteLine("B::Foo()"); }
}

and you again get the output

A::Foo()
B::Foo()
A::Foo()
Juri
question is market C# as you see
ArsenMkrt
Juri highlights a difference with Java, but he is talking about C#...
jeroenh