2

I've been doing a little reading around the c# spec, and come across a scenario I didn't expect, and was hoping somebody could share some light.

I stumbled across the new keyword for hiding members of a base class within a derived class, and subsequently a few discussions over when to use new as opposed to an override on a virtual member.

I threw a little code sample in to my IDE, expecting to see a compilation error

public class BaseType
{
    public void method()
    {
        // do nothing
    }
}
public class DerivedType : BaseType
{
    public new void method()
    {
        base.method();
    }
}

but instead found this to be legal c#. Since the derived class has hidden the presence of method(), why am I still allowed to call it?

Cheers

Deleted
  • 31
  • 2

2 Answers2

4

The DerivedType is hiding the method from the classes which will be inheriting DerivedType, and not from itself.
Note that, to hide the method, the class has to know there exists a method in it's parent class with the same name and same arguments. Hence a class hiding the method from it's own scope is logically incorrect.

Ganesh Jadhav
  • 2,830
  • 1
  • 20
  • 32
3

Do not mix method hiding with method overriding. They are two completely different beasts.

When hiding a method, you are only hiding it when accessing the method through the type that hides the method to begin with:

public class Foo
{
    public string Blah() { return "Hi from Foo!"; }
}

public class DerivedFoo: Foo
{
    public new string Blah() { return "Hi from DerivedFoo!"; }
}

Now we have the following behavior:

void TestFoos()
{
    Foo foo = new Foo();
    DerivedFoo derivedFoo = new DerivedFoo();
    Foo derivedFooInDisguise = derivedFoo as Foo;

    Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
    Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
    Console.WriteLine(derivedFooInDisguise.Blah()); //Outputs "Hi from Foo!" 
}

Note, that this behavior is the same even if Blah is declared as virtual. The interesting part is the third call. The method is invoked through a Foo typed object. As its not a virtual call, Foo.Blah() is called, not DerivedFoo.Blah().

Now this is completely different from method overriding where the virtual method call always resolves to the runtime type of the object, not the type through which you are calling it:

public class Foo
{
    public virtual string Blah() { return "Hi from Foo!"; }
}

public class DerivedFoo: Foo
{
    public override string Blah() { return "Hi from DerivedFoo!"; }
}

Now we have the following behavior:

void TestFoos()
{
    Foo foo = new Foo();
    DerivedFoo derivedFoo = new DerivedFoo();
    Foo derivedFooInDisguise = derivedFoo as Foo;

    Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
    Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
    Console.WriteLine(derivedFooInDisguise.Blah()); ////Outputs "Hi from DerivedFoo!"
} 
InBetween
  • 32,319
  • 3
  • 50
  • 90
  • While this is a good indication of the separation of one over the other, and it's appreciated, the question was more, why was the snipped posted legal c#, when my expectation was that this would be invalid. – Deleted Aug 19 '14 at 16:59
  • @JamieR Sorry, I completely misunderstood your question. Out of curiosity, why do you find it surprising when hiding but not when overriding? – InBetween Aug 19 '14 at 18:11
  • My mistake was assuming that the declaration of hiding the method of `BaseType` would make the method invisible immediately to `DerivedType`, whereas the method is in fact hidden for consumers and children of `DerivedType`. – Deleted Aug 20 '14 at 11:45