This is an area of C# where there is a big "gotcha". Using the new
keyword or using the virtual
+ override
keywords behave very differently, we will start with virtual.
Virtual and override
If we have the following class MyClass
with a virtual Get()
method:
public class MyClass
{
public virtual string Get()
{
return "MyClass";
}
}
We then create a class that inherits from MyClass
and overrides the Get()
method.
public class MyOverriddenClass : MyClass
{
public override string Get()
{
return "MyOverriddenClass";
}
}
If we instantiate MyOverriddenClass
and call the method Get()
, we get the string "MyOverriddenClass":
MyClass originalClass = new MyOverriddenClass(); //Declared as "MyClass" not "MyOverriddenClass"
Assert.AreEqual("MyOverriddenClass", originalClass.Get()); //passes
MyOverriddenClass overridenClass = new MyOverriddenClass();
Assert.AreEqual("MyOverriddenClass", overridenClass.Get()); //passes
The result is the same whether we declare it as MyClass
or MyOverridenClass
. Does this surprise you? It should not, the surprise is in the difference when we get to the new
keyword - read on.
New Keyword
We will reuse the MyClass
class from before (without virtual
keyword) and make a MyNewClass
class which uses the new
keyword instead of override
:
public class MyClass
{
public string Get()
{
return "MyClass";
}
}
public class MyNewClass : MyClass
{
public new string Get()
{
return "MyClassUsingNew";
}
}
If we do the same test as we did before:
MyClass originalClass = new MyNewClass(); //Declared as "MyClass" not "MyNewClass"
Assert.AreEqual("MyClassUsingNew", originalClass.Get()); //fails
MyNewClass overridenClass = new MyNewClass();
Assert.AreEqual("MyClassUsingNew", overridenClass.Get()); //passes
We see that the first assertion now fails. It calls the original method on MyClass
rather than the new method on MyNewClass
. This is because the new
keyword creates a completely different method that only exists in that class. That is the big difference between using new or virtual/override keywords. Using virtual
you can signal that this method is supposed to be overridden and then override it specifically with the override
keyword. Using new
you are creating a new method and hiding the original implementation (I like to think with brute force) and there is no relation between the two.
That is all
I hope you found this useful, please leave a comment down below if this was helpful - or even if not :)