Back to Blog
C#

C# new vs override: Choosing the Right Member Hiding Strategy

c# new vs override: Understand the difference between C# new and override keywords, when to use each, and how they affect polymorphism and runtime behavior.

C#inheritancemethod hidingoverridepolymorphism
Diagram comparing C# new and override behavior in inheritance, showing method resolution through base class references.

c# new vs override requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

In C#, the new and override keywords both allow a derived class to declare a method that has the same signature as a base class method. The difference is not syntactic preference; it changes how the method is dispatched at runtime and how it behaves when accessed through a base class reference. Understanding this distinction is essential for designing inheritance hierarchies that behave predictably.

What new and override Actually Do

The override keyword is used to replace a virtual method declared in a base class. The base method must be marked virtual (or abstract), and the derived method becomes part of the same virtual method slot. When you call the method through a base class reference, the runtime looks up the most derived override and executes it. This is the foundation of polymorphism.

The new keyword, on the other hand, hides a method that exists in the base class. The base method does not need to be virtual. The derived method is a completely separate method that happens to have the same name and signature. If you call the method through a base class reference, the base class method runs, not the derived one. The new keyword simply suppresses the compiler warning that would otherwise appear when you hide a member without an explicit keyword.

How Method Resolution Works with Base Class References

Consider a simple hierarchy:

public class Base { public virtual void Show() { Console.WriteLine("Base.Show"); } } public class DerivedOverride : Base { public override void Show() { Console.WriteLine("DerivedOverride.Show"); } } public class DerivedNew : Base { public new void Show() { Console.WriteLine("DerivedNew.Show"); } }

Now create instances and call Show through a Base reference:

Base b1 = new DerivedOverride(); b1.Show(); // Output: DerivedOverride.Show Base b2 = new DerivedNew(); b2.Show(); // Output: Base.Show

When the method is override, the runtime uses the actual type of the object (DerivedOverride) to resolve the call. When the method is new, the compiler uses the static type of the reference (Base) to resolve the call. This behavior is consistent even if you cast the reference to Base explicitly.

When to Use override

Use override when you want the derived class to provide a different implementation of a base method, and you want that implementation to be used regardless of the reference type. This is the correct choice for methods that represent polymorphic behavior, such as ToString(), Equals(), or any method that should vary based on the actual object type.

For example, a Shape base class might have a virtual Area() method. Each derived shape overrides it to compute its own area. When you iterate over a collection of Shape references, calling Area() on each element invokes the correct implementation because of overriding.

When to Use new

The new keyword is appropriate when you intentionally want to hide a base method and do not want polymorphic dispatch. This is rare in well-designed hierarchies, but it can be useful when the base class is not under your control and you want to provide a method with the same name that behaves differently for your derived class—but only when the caller knows the derived type.

A common scenario is when you inherit from a third-party class and need to add a method that happens to have the same name as an existing non-virtual method. Using new allows you to define your own method without altering the base class behavior. However, this can lead to subtle bugs because calls through base references still hit the base implementation.

Common Pitfalls and Misunderstandings

One frequent mistake is assuming that new and override are interchangeable when the base method is virtual. If you use new on a virtual method, you break the override chain. Any further derived class that tries to override the method will override the base virtual method, not your new method, unless it also uses new again. This can cause confusing behavior.

Another issue is the compiler warning CS0108, which appears when you hide a base member without new. The warning is a signal that you might be doing something unintended. If you see it, decide whether you actually want to hide the method or whether you should use override instead.

Consider this example:

public class Base { public void Log() { Console.WriteLine("Base.Log"); } } public class Derived : Base { public void Log() { Console.WriteLine("Derived.Log"); } // Warning CS0108 }

Adding new suppresses the warning but does not change the runtime behavior. The method is still hidden, not overridden.

Practical Example: Extending a Base Class

Suppose you have a base class that provides a Save() method, and you want to add extra behavior in a derived class without breaking existing callers that use base references.

public class Repository { public void Save() { // Save to database Console.WriteLine("Saving to database"); } } public class LoggingRepository : Repository { public new void Save() { Console.WriteLine("Logging before save"); base.Save(); Console.WriteLine("Logging after save"); } }

If you call Save() on a LoggingRepository variable, the new method runs. But if you assign it to a Repository variable, the base Save() runs, and the logging is skipped. This is often not what developers expect. If you need polymorphic behavior, the base method should be virtual and the derived method should use override.

Maintainability and Compatibility Considerations

The choice between new and override has long-term consequences. Overriding a virtual method preserves polymorphism and makes your derived class work correctly in generic code that operates on base types. Hiding a method with new creates a fragile situation: if the base class later adds a virtual keyword to that method, your new method will not automatically become an override, and the behavior may change unexpectedly.

When you design a base class, marking a method as virtual is a commitment that derived classes can override it. If you do not want that flexibility, leave it non-virtual. When you write a derived class, prefer override whenever the base method is virtual and you want to replace its behavior. Use new only when you are certain that the method should be hidden and that callers will always use the derived type.

In a codebase, excessive use of new can make inheritance hierarchies harder to reason about. A developer reading a call site that uses a base reference cannot know whether the actual implementation is the base method or a hidden one, because the compiler resolves it based on the reference type. This hidden dependency often leads to bugs that are difficult to trace. Overriding, by contrast, makes the runtime behavior explicit and predictable.

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