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()