Composite Pattern in C#
The Composite Pattern lets you treat individual objects and groups of objects the same way. It is very useful when working with tree-like structures — where parts can be made of smaller parts.
Real-Life Analogy: Folders and Files
Imagine your computer's file system. You have files like report.pdf
, and folders like Projects
.
A folder can contain files, but also other folders. And those folders can contain even more items.
No matter what you're dealing with — a file or a folder — you can perform the same actions: open, delete, move, or rename. That's exactly what the Composite Pattern is about — working with individual items and groups using the same interface.

Benefits of Composite Pattern
This pattern helps you build flexible tree structures that allow uniform operations on both leaves and composites. You can work with complex hierarchies without writing code that treats them differently.
It simplifies recursive operations and allows new composite types to be added with ease.
- Treats objects and collections uniformly
- Simplifies tree-like processing
- Supports flexible and extendable structures
When Should You Use It?
Use the Composite Pattern when you want to treat a group of objects the same way as a single object. It works especially well for hierarchical or nested data models.
Ideal use cases include:
- File systems
- Graphic elements (e.g. UI containers and controls)
- Organisation charts
When Not to Use It: Avoid it if your structure is flat or does not contain nested elements — a simple list might be enough.
What to Implement
You need:
A shared interface for both simple and complex objects, plus leaf and composite classes.
- Component Interface: Declares common operations
- Leaf: Represents individual objects
- Composite: Holds child components and applies operations to them
How It Works in C#
// Component Interface
public interface IFileSystemItem
{
void Display(int indent = 0);
}
// Leaf
public class FileItem : IFileSystemItem
{
private readonly string _name;
public FileItem(string name) => _name = name;
public void Display(int indent = 0)
{
Console.WriteLine($""{new string(' ', indent)}- File: {_name}"");
}
}
// Composite
public class Folder : IFileSystemItem
{
private readonly string _name;
private readonly List<IFileSystemItem> _items = new();
public Folder(string name) => _name = name;
public void Add(IFileSystemItem item) => _items.Add(item);
public void Display(int indent = 0)
{
Console.WriteLine($""{new string(' ', indent)}+ Folder: {_name}"");
foreach (var item in _items)
item.Display(indent + 2);
}
}
Usage:
var root = new Folder("Projects");
var subFolder = new Folder("2025");
subFolder.Add(new FileItem("invoice.pdf"));
subFolder.Add(new FileItem("design.png"));
root.Add(new FileItem("readme.txt"));
root.Add(subFolder);
root.Display();
Final Thoughts
The Composite Pattern helps you organise nested structures cleanly and work with them as if they were flat. Whether you're dealing with one item or many, your code stays simple and consistent.
It's a great fit for any structure where parts and wholes should behave the same.