Override vs New Polymorphism In C# .NET

I was recently asked by another developer on the difference between making a method virtual/override, and simply hiding the method using the new keyword in C#.

I gave him what I thought to be the best answer (For example, you can change the return type when using the “new” keyword), and yet while showing him examples I managed to bamboozle myself into learning something new after all these years.

Take the following code for instance, what will it print?

Parent childOverride = new ChildOverride();

Parent childNew = new ChildNew();

class Parent
    public virtual void WhoAmI()

class ChildOverride : Parent
    public override void WhoAmI()

class ChildNew : Parent
    public new void WhoAmI()

At first glance, I assumed it would print the same thing either way. After all, I’m basically newing up the two different types, and in *both* cases I am casting it to the parent.

When casting like this, I like to tell junior developers that an object “Always remembers who it is”. That is, my ChildOverride can be cast to a Parent, or even an object, and it still remembers that it’s a ChildOverride.

So what does the above code actually print out?


So our Override method remembered who it was, and therefore it’s “WhoAmI” method. But our ChildNew did not… Kinda.

Why you might ask? Well it actually is quite simple if you think about it.

When you use the override keyword, it’s overriding the base class and there is a sort of “linkage” between the two methods. That is, it’s known that the child class is an override of the base.

When you use the new keyword, you are saying that the two methods are in no way related. And that your new method *only* exists on the child class, not on the parent. There is no “linkage” between the two.

This is why when you cast to the parent class, the overridden method is known, and the “new” method is not.

With all that being said, in many many years of programming in C# I have seldomly used the new keyword to override methods like this. Not only is there very little reason to do so, but it breaks a core SOLID principle in the Liskov Principle : https://dotnetcoretutorials.com/2019/10/20/solid-in-c-liskov-principle/

Leave a Comment