Back to Blog
C#

C# New Method Hiding: Syntax and Runtime Behavior

c# new method hiding: Understand how C# new method hiding works, how it differs from overriding, and when hiding is the right design choice for your class hierarchy.

C#method hidinginheritancepolymorphismnew modifier
Diagram showing a base class method being hidden by a derived class method with the new modifier in C#

C# new method hiding is the mechanism by which a derived class declares a member with the same name and signature as a base-class member without overriding it. The new modifier makes that intent explicit, and the compiler treats the two members as unrelated. Understanding this behavior matters because it changes how calls are resolved at runtime and can silently alter program behavior depending on the declared type of a variable.

What Method Hiding Does in C#

When a derived class declares a member with the same name and signature as a base-class member, and that base member is not virtual, the derived member hides it. The new modifier suppresses the compiler warning and documents that the hiding is deliberate.

public class BaseClass { public void Display() { Console.WriteLine("Base display"); } } public class DerivedClass : BaseClass { public new void Display() { Console.WriteLine("Derived display"); } }

Calling Display through a DerivedClass reference executes the derived implementation. Calling it through a BaseClass reference executes the base implementation. The method is not virtual, so the runtime does not consider the actual object type when selecting which method to invoke.

How Hiding Differs from Overriding

Overriding requires a virtual method in the base class and an override modifier in the derived class. The runtime then uses the actual object type to select the implementation, regardless of the static type of the reference.

public class BaseClass { public virtual void Display() { Console.WriteLine("Base display"); } } public class DerivedClass : BaseClass { public override void Display() { Console.WriteLine("Derived display"); } }

With overriding, both a BaseClass reference and a DerivedClass reference produce the derived output when the object is actually a DerivedClass. With hiding, the static type of the reference determines which method runs. That distinction is the core difference between the two mechanisms.

Runtime Behavior: Static Dispatch and Call Sites

Method hiding uses static dispatch. The compiler resolves the call at compile time based on the declared type of the variable, not the runtime type of the object. This has a direct consequence: hiding a method changes behavior depending on how the object is referenced.

BaseClass b = new DerivedClass(); b.Display(); // "Base display" DerivedClass d = new DerivedClass(); d.Display(); // "Derived display"

This asymmetry is the main source of confusion. If a method is hidden, code that receives the object through a base-class reference continues to call the base implementation. That can be intentional, but it also means the derived behavior is not consistently applied across all call sites.

Why the CS0108 Warning Matters

The compiler emits warning CS0108 when a derived member hides an inherited member without the new modifier. The warning is not an error, but it signals a likely mistake: the developer probably intended to override but forgot to mark the base method virtual.

public class DerivedClass : BaseClass { public void Display() // CS0108 warning { Console.WriteLine("Derived display"); } }

Adding new suppresses the warning and documents the intent. Changing the base method to virtual and using override instead changes the runtime behavior, so the decision should be deliberate rather than a reflex to silence the compiler.

When Method Hiding Is Useful

Method hiding is appropriate when you want to provide a different implementation for callers who use the derived type directly while preserving the base behavior for callers who use the base type. This is uncommon in application code but can appear in framework scenarios where you cannot modify the base class.

A common pattern is hiding a property to return a more specific type:

public class Repository { public object GetData() => LoadFromDatabase(); } public class UserRepository : Repository { public new User GetData() => LoadUser(); }

Callers who know they have a UserRepository get the typed result without a cast. Callers who only have a Repository still get the base behavior. This works because the two methods are unrelated at the runtime level, and each call site binds to the method matching its declared type.

Maintainability and Compatibility Concerns

Method hiding introduces a maintenance burden because the behavior of a call depends on the static type of the reference. If a developer changes a variable's declared type from DerivedClass to BaseClass, the behavior silently changes. This makes code harder to reason about than virtual dispatch, where the actual object type consistently determines behavior.

Hiding also creates a compatibility trap when the base class later adds a member with the same signature. The derived class's new member then hides a member the base author may not have anticipated, and callers through the base type get the base implementation even when the object is derived. This can produce subtle bugs that only surface when a third-party library is upgraded.

When you control the base class, prefer virtual and override for polymorphic behavior. Reserve new for cases where you intentionally want type-dependent behavior and you are certain callers will use the derived type directly.

Edge Cases: Hiding Virtual Members and Interface Members

You can hide a virtual member with new. The result is that the hidden member is no longer virtual for the derived hierarchy. Calls through a base reference still dispatch virtually to the original virtual method, but calls through the derived type reference invoke the new non-virtual member.

public class BaseClass { public virtual void Display() { } } public class DerivedClass : BaseClass { public new void Display() { } } public class FurtherDerived : DerivedClass { public override void Display() { } // error: no virtual member to override }

This combination splits the hierarchy into two parallel method sets and makes further inheritance confusing. A class further down the hierarchy cannot override the hidden member because it is no longer virtual. If you find yourself hiding a virtual member, reconsider whether overriding is the correct approach.

Interface members can also be hidden. When a class implements an interface implicitly and a derived class hides the implementing member, interface calls through the interface reference still dispatch to the original implementation. This is another case where the call-site type determines behavior, and it can surprise developers who expect interface dispatch to follow the object's runtime type.

c# new method hiding: Practical Usage and Code Examples | RYUSLOG DEV