The difference between new and override

Let's say you have a base class with a single method on it

public class BaseClass
{
    public new void SomeMethod()
    {
        Console.WriteLine("Called BaseClass.SomeMethod");
    }
}

Now imagine a scenario where you want to derive from that class and create a new implementation of SampleMethod

public class DerivedClass : BaseClass
{
    public void SomeMethod()
    {
        Console.WriteLine("Called DerivedClass.SomeMethod");
    }
}

You'll notice when you enter this code sample that the ReSharper suggests you add the 'new' keyword as it hides the method in BaseClass. You can get away without adding new but you will get a compiler warning. If, however, you choose to follow that advice you'll end up with the following class.

public class DerivedClass : BaseClass
{
    public new void SomeMethod()
    {
        Console.WriteLine("Called DerivedClass.SomeMethod");
    }
}

Let's have a look at what that new keyword has done by running the following code.

BaseClass baseClass = new DerivedClass();
baseClass.SomeMethod();
DerivedClass derivedClass = new DerivedClass();
derivedClass.SomeMethod();

You might be surprised to see the following output

Called BaseClass.SomeMethod
Called DerivedClass.SomeMethod

Before I tell you what's going on here let's look at what happens when we use the alternative and add the virtual keyword to SomeMethod in the BaseClass and then override it in the derived class.

public class BaseClass
{
    public virtual void SomeMethod()
    {
        Console.WriteLine("Called BaseClass.SomeMethod");
    }
}

public class DerivedClass : BaseClass
{
    public override void SomeMethod()
    {
        Console.WriteLine("Called DerivedClass.SomeMethod");
    }
}

If we then re-run the code above we now see the following output

Called DerivedClass.SomeMethod
Called DerivedClass.SomeMethod

The reason behind this difference in behaviour is all to do with polymorphism. When you give a method the virtual keyword you're telling the compiler to make a runtime check of what the actual type of the instance is. When you use the new keyword all you are doing is hiding the instance of the method in the base class and there is no runtime check of the actual type. This means that if a method signature takes in the base class or you are have declared the type of the instance of your class as BaseClass then the base class instance of the method is all the compiler knows about so this is the method that it uses. Until you understand the difference this can be quite confusing behaviour.

For those of you interested, if you do choose not to add the new keyword you see the same behaviour as if you had. All you're actually doing by adding the new keyword is telling the compiler that you intentionally meant to hide the base class implementation.