Back to Blog
C#

C# Interface Inheritance: Syntax and Usage

c# interface inheritance: Learn how C# interfaces inherit from other interfaces, implement derived interfaces, and handle multiple inheritance with practical examples.

interfaceinheritanceC#object-oriented programmingtype design
Diagram showing interface inheritance hierarchy in C# with derived interfaces and implementing classes.

In C#, an interface can inherit from one or more other interfaces. This is known as C# interface inheritance. When an interface inherits from a base interface, it includes all members of the base interface in its contract. Any class or struct that implements the derived interface must provide implementations for every member from the entire inheritance chain.

Interface Inheritance Syntax

Declaring an interface that inherits from another interface uses the same colon syntax as class inheritance. The derived interface lists the base interface after the colon.

public interface IShape { double Area { get; } } public interface IColoredShape : IShape { string Color { get; set; } }

Here, IColoredShape inherits Area from IShape and adds Color. A class implementing IColoredShape must implement both properties, not just the one declared directly in IColoredShape.

Implementing a Derived Interface

When a class implements a derived interface, it must provide concrete implementations for all members across the entire interface hierarchy. The compiler enforces this at compile time.

public class Circle : IColoredShape { public double Radius { get; set; } public double Area => Math.PI * Radius * Radius; public string Color { get; set; } }

If you omit Area or Color, the code will not compile. This behavior is identical to implementing a single interface, but the member list is expanded to include inherited members.

Multiple Interface Inheritance

An interface can inherit from multiple base interfaces. This allows you to compose a contract from several smaller, focused interfaces.

public interface IResizable { void Resize(double factor); } public interface IShape { double Area { get; } } public interface IResizableShape : IShape, IResizable { void Move(int x, int y); }

A class implementing IResizableShape must implement Area, Resize, and Move. Multiple interface inheritance is a key tool for building modular type contracts without the complications of multiple class inheritance.

Member Hiding and Re-Declaration

An interface can re-declare a member that it inherits. This is called member hiding. The derived interface can specify a new signature or just repeat the same signature. Re-declaring a member does not remove the original; it simply makes the derived interface's member the one that must be implemented.

public interface IBase { void DoWork(); } public interface IDerived : IBase { new void DoWork(); }

When a class implements IDerived, it must provide a DoWork method. The new keyword suppresses a compiler warning but does not change the runtime behavior. The class implementation satisfies both interfaces because the method signature is identical.

Practical Use Cases

Interface inheritance is valuable when you want to express a hierarchy of capabilities. For example, a logging interface can inherit from a base ILogger and add structured logging methods. This lets you write code that depends on the derived interface while remaining substitutable for the base interface.

public interface ILogger { void Log(string message); } public interface IStructuredLogger : ILogger { void LogStructured(string message, IDictionary<string, object> properties); }

Consumers that only need basic logging can accept ILogger, while advanced consumers can require IStructuredLogger. This keeps dependencies narrow and testable.

Runtime and Maintainability Considerations

Interface inheritance has no runtime overhead; it is purely a compile-time contract. The runtime cost of a virtual call through an interface is the same whether the interface is a base or derived. The real tradeoff is maintainability. Deep interface hierarchies can become difficult to navigate, and changing a base interface forces changes across all derived interfaces and implementing classes.

When designing interface hierarchies, prefer shallow trees. If a derived interface adds only one or two members, consider whether the base interface is genuinely reusable. If not, a single flat interface may be simpler. Interface inheritance is most useful when you have a clear, stable base contract that multiple derived contracts extend.

Common Pitfalls and Edge Cases

One common pitfall is ambiguity when two base interfaces declare the same member with the same signature. C# resolves this without error because the implementing class provides a single method that satisfies both. However, if the two base interfaces declare the same member with different signatures, the derived interface must re-declare the member or the class must use explicit interface implementation.

public interface ILeft { void Draw(); } public interface IRight { void Draw(); } public interface IBoth : ILeft, IRight { } public class Widget : IBoth { public void Draw() { } }

This compiles because Draw() satisfies both interfaces. If you need different implementations per interface, use explicit interface implementation.

public class Widget : IBoth { void ILeft.Draw() { /* left-specific */ } void IRight.Draw() { /* right-specific */ } }

Explicit implementation is the only way to provide distinct behavior for inherited members with identical signatures. It also hides the method from the class's public API unless called through the interface.

Another edge case is when a derived interface adds a member that already exists in a base interface with a different return type. C# does not allow overloading based on return type alone, so the derived interface must use the new keyword to hide the base member. This can lead to confusion and should be avoided unless absolutely necessary.

Interface inheritance is a powerful feature when used deliberately. Keep hierarchies shallow, re-declare members only when needed, and use explicit implementation when multiple base interfaces require distinct behavior. By understanding these rules, you can design interfaces that are both flexible and maintainable.

c# interface inheritance: Practical Usage and Code Examples | RYUSLOG DEV