How to implement Open Closed principle using C#?

The Open Closed Principle (OCP) is one of the five SOLID principles of object-oriented programming. It states that software entities like classes, modules and functions should be open for extension but closed for modifications.

Definition

The Open Closed Principle states that the design and writing of code should be done in a way that new functionality can be added with minimum changes to existing code. The design should allow adding new functionality through new classes while keeping existing code unchanged as much as possible.

Open Closed Principle OPEN for Extension Add new features through inheritance CLOSED for Modification Don't change existing code Extend behavior without modifying source code Use abstraction and polymorphism

Code Before Open Closed Principle

The following example violates the Open Closed Principle because adding a new shape requires modifying the existing calculator class −

using System;

namespace SolidPrinciples.Open.Closed.Principle.Before {
    public class Rectangle {
        public int Width { get; set; }
        public int Height { get; set; }
    }

    public class Circle {
        public double Radius { get; set; }
    }

    // Violates OCP - needs modification for each new shape
    public class CombinedAreaCalculator {
        public double Area(object[] shapes) {
            double area = 0;
            foreach (var shape in shapes) {
                if (shape is Rectangle) {
                    Rectangle rectangle = (Rectangle)shape;
                    area += rectangle.Width * rectangle.Height;
                }
                if (shape is Circle) {
                    Circle circle = (Circle)shape;
                    area += (circle.Radius * circle.Radius) * Math.PI;
                }
                // Adding Triangle would require modifying this method
            }
            return area;
        }
    }

    public class Program {
        public static void Main() {
            object[] shapes = { 
                new Rectangle { Width = 5, Height = 4 }, 
                new Circle { Radius = 3 } 
            };
            
            CombinedAreaCalculator calculator = new CombinedAreaCalculator();
            double totalArea = calculator.Area(shapes);
            Console.WriteLine("Total Area: " + totalArea);
        }
    }
}

The output of the above code is −

Total Area: 48.2743338823081

Code After Open Closed Principle

The following implementation follows the Open Closed Principle using abstraction. New shapes can be added without modifying existing code −

using System;

namespace SolidPrinciples.Open.Closed.Principle.After {
    public abstract class Shape {
        public abstract double Area();
    }

    public class Rectangle : Shape {
        public int Width { get; set; }
        public int Height { get; set; }
        
        public override double Area() {
            return Width * Height;
        }
    }

    public class Circle : Shape {
        public double Radius { get; set; }
        
        public override double Area() {
            return Radius * Radius * Math.PI;
        }
    }

    // New shape added without modifying existing classes
    public class Triangle : Shape {
        public double Base { get; set; }
        public double Height { get; set; }
        
        public override double Area() {
            return 0.5 * Base * Height;
        }
    }

    // Calculator remains unchanged regardless of new shapes
    public class CombinedAreaCalculator {
        public double Area(Shape[] shapes) {
            double area = 0;
            foreach (var shape in shapes) {
                area += shape.Area();
            }
            return area;
        }
    }

    public class Program {
        public static void Main() {
            Shape[] shapes = { 
                new Rectangle { Width = 5, Height = 4 }, 
                new Circle { Radius = 3 },
                new Triangle { Base = 6, Height = 8 }
            };
            
            CombinedAreaCalculator calculator = new CombinedAreaCalculator();
            double totalArea = calculator.Area(shapes);
            Console.WriteLine("Total Area: " + totalArea);
        }
    }
}

The output of the above code is −

Total Area: 72.2743338823081

Key Benefits

Before OCP After OCP
Modification required for new features Extension through new classes only
Risk of breaking existing functionality Existing code remains untouched
Type checking with if-else statements Polymorphism handles type differences
Tightly coupled code Loosely coupled through abstraction

How It Works

The Open Closed Principle is achieved through abstraction and polymorphism. By creating an abstract base class or interface, we define a contract that derived classes must follow. The calculator class depends on the abstraction, not concrete implementations, making it extensible without modification.

Conclusion

The Open Closed Principle promotes code that is extensible yet stable. By using abstraction and polymorphism, new functionality can be added through inheritance without modifying existing tested code, reducing bugs and improving maintainability.

Updated on: 2026-03-17T07:04:36+05:30

586 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements