Back to Blog
C#

C# override vs new: Choosing the Right Method Behavior

c# override vs new: Understand the practical difference between override and new in C#: how they affect polymorphism, virtual dispatch, and when to use each.

C#method overridingmethod hidingpolymorphisminheritancevirtual methods
Diagram showing override and new method behavior in C# inheritance

When you declare a method in a derived class that has the same signature as a method in the base class, C# gives you two choices: override or new. The choice changes how the method behaves at runtime and how it interacts with polymorphism. This article explains the technical difference between c# override vs new, with code examples and practical guidance.

The Core Difference Between override and new

override extends or replaces a virtual method from the base class, and it participates in polymorphic dispatch. new hides the base method entirely, creating a separate method that is only called when the object is referenced through the derived type. The distinction matters when you call a method through a base-class reference.

Consider this base class:

public class Animal { public virtual void Speak() { Console.WriteLine("Animal speaks"); } }

A derived class can override or hide Speak. The compiler treats these as two different operations, and the runtime behavior differs significantly.

How Virtual Dispatch Works in C#

Virtual dispatch is the mechanism that allows the runtime to call the most derived implementation of a virtual method. When you mark a method as virtual, the runtime uses a vtable (virtual method table) to resolve the call based on the actual type of the object, not the type of the reference.

If a derived class uses override, it replaces the base implementation in the vtable for that specific type. Any call through a base-class reference to that object will invoke the override. If the derived class uses new, it does not modify the vtable entry; it creates a completely separate method that is not part of the virtual dispatch chain.

Using override to Extend Base Class Behavior

When you use override, you are explicitly stating that the derived method is the implementation that should be called polymorphically. The base method must be marked virtual, abstract, or already override another method. The signature must match exactly, and the access modifier cannot be more restrictive than the base method.

public class Dog : Animal { public override void Speak() { Console.WriteLine("Dog barks"); } }

Now, whether you call Speak through an Animal reference or a Dog reference, the output is always "Dog barks". This is the expected behavior for most inheritance scenarios where you want derived types to provide specialized behavior while keeping a common interface.

Using new to Hide a Base Class Method

The new keyword in a method declaration hides the base method. It does not require the base method to be virtual. The derived method is independent; it does not override anything. The compiler will issue a warning if you omit new and hide a method without it, but the behavior is the same.

public class Cat : Animal { public new void Speak() { Console.WriteLine("Cat meows"); } }

If you call Speak on a Cat reference, you get "Cat meows". But if you assign a Cat instance to an Animal variable and call Speak, the runtime uses virtual dispatch and finds no override, so it calls the base Animal.Speak and outputs "Animal speaks". This is the key difference: new breaks polymorphism.

Runtime Behavior: Which Method Gets Called?

The method that executes depends on the compile-time type of the reference and whether the method is virtual. For an override, the runtime looks up the vtable and calls the most derived implementation. For a new method, the compiler emits a call to the method based on the static type of the reference.

Animal animal = new Dog(); animal.Speak(); // Dog barks (override) Animal animal2 = new Cat(); animal2.Speak(); // Animal speaks (new hides, no override) Cat cat = new Cat(); cat.Speak(); // Cat meows (new method)

This behavior is consistent with the C# specification. The override keyword is the only way to participate in virtual dispatch. The new keyword is a compile-time directive that tells the compiler you intentionally hide the base method, suppressing the warning but not changing the runtime resolution.

Common Pitfalls and How to Avoid Them

The most common mistake is using new when you intend polymorphic behavior. This often happens when a developer adds a method with the same name as a base method but forgets to mark the base method as virtual. The result is that calls through base-class references silently invoke the base implementation, which can lead to subtle bugs.

Another pitfall is mixing override and new in a long inheritance chain. If a derived class overrides a method that was hidden in an intermediate class, the override still applies to the original virtual method. The hiding in the intermediate class only affects calls that go through that intermediate type. This can create confusing behavior if you are not careful about the exact types in the call chain.

To avoid these issues, always ask whether the method should be polymorphic. If it should, mark the base method virtual and use override. If you are intentionally providing a non-polymorphic alternative, use new and document why.

Choosing Between override and new in Real Code

Use override when you want derived classes to provide a specialized implementation that is callable through a base interface. This is the standard pattern for frameworks, plugins, and any design that relies on polymorphism.

Use new when you need to add a method with the same name as a base method but you do not want it to participate in virtual dispatch. This is rare and usually indicates a design issue. For example, if you are extending a sealed class or a class where the base method is not virtual, new is the only way to define a method with the same signature. But you should consider renaming the method to avoid confusion.

A practical guideline: if you find yourself using new frequently, reconsider the inheritance hierarchy. It may be better to use composition or to redesign the base class so that the method is virtual.

Compatibility and Maintainability Considerations

The choice between override and new has long-term maintainability implications. override preserves the contract of the base class and ensures that derived types behave consistently when used polymorphically. new can break that contract and cause unexpected behavior for consumers who hold a base-class reference.

When you change a base method from non-virtual to virtual, any existing new methods in derived classes will not automatically become overrides. They will continue to hide the base method, and the compiler will not warn you. This can silently change behavior if you later add an override in a subclass. To maintain clarity, always document the intent of each method that uses new, and consider adding a comment explaining why hiding is necessary.

From a runtime perspective, override adds a vtable lookup, which is a negligible cost in most applications. new methods are called directly, but the difference is not significant enough to drive the decision. The primary factor should be the semantic correctness of the design, not micro-optimization.

In production code, the most reliable approach is to avoid new unless you have a concrete reason that cannot be solved with a different method name. When you do use it, make sure the hiding behavior is intentional and well understood by the entire team. Prefer override for any method that represents a behavior that should be replaceable by derived types.

c# override vs new: Practical Usage and Code Examples | RYUSLOG DEV