SOLID: The Liskov Substitution Principle (LSP) in C#
Aditya

Aditya @extinctsion

About: Software Engg | Making things ↔ complicated is my hobby.

Location:
New Delhi, India
Joined:
Nov 14, 2021

SOLID: The Liskov Substitution Principle (LSP) in C#

Publish Date: Dec 19 '24
49 13

Introduction

The Liskov Substitution Principle (LSP) is a foundational concept in object-oriented design, introduced by Barbara Liskov in 1987. It states:

"Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program."

In simpler terms, derived classes must be substitutable for their base classes without altering the expected behavior of the program. LSP ensures that a class hierarchy is designed in a way that promotes reusability and reliability.

Inheritance

Key Aspects of LSP

  1. Behavioral Consistency: Subclasses must adhere to the behavior defined by their base classes.
  2. No Surprises: A subclass should not override or weaken any functionality of the base class.
  3. Contracts: Subclasses should honor the "contract" (e.g., preconditions and postconditions) established by the base class.

Violating LSP often leads to fragile code that is hard to maintain or extend.

Bad code ❌

public class Rectangle
{
    public virtual double Width { get; set; }
    public virtual double Height { get; set; }

    public double GetArea() => Width * Height;
}

public class Square : Rectangle
{
    public override double Width
    {
        set { base.Width = base.Height = value; }
    }

    public override double Height
    {
        set { base.Width = base.Height = value; }
    }
}

public class LSPViolationDemo
{
    public static void Main()
    {
        Rectangle rectangle = new Square(); // Substitution occurs here
        rectangle.Width = 4;
        rectangle.Height = 5; // Expecting Width=4 and Height=5 for a rectangle

        Console.WriteLine($"Area: {rectangle.GetArea()}"); // Output: 25, not 20!
    }
}
Enter fullscreen mode Exit fullscreen mode

What's Wrong? ❌

Substituting Square for Rectangle violates expectations. A rectangle can have different widths and heights, but a square enforces equal sides. The GetArea result is incorrect in this context.

Adhering to LSP: A Better Design ✔

Inheritance

To adhere to LSP, avoid forcing subclasses into incompatible behaviors. In this case, separating Rectangle and Square into distinct hierarchies solves the issue:

public abstract class Shape
{
    public abstract double GetArea();
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public override double GetArea() => Width * Height;
}

public class Square : Shape
{
    public double SideLength { get; set; }

    public override double GetArea() => SideLength * SideLength;
}

public class LSPAdherenceDemo
{
    public static void Main()
    {
        Shape rectangle = new Rectangle { Width = 4, Height = 5 };
        Shape square = new Square { SideLength = 4 };

        Console.WriteLine($"Rectangle Area: {rectangle.GetArea()}");
        Console.WriteLine($"Square Area: {square.GetArea()}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Why This Works?

  1. Both Rectangle and Square derive from Shape, but they operate independently, adhering to their specific behaviors.
  2. LSP is preserved because the substitution respects each class's expected behavior.

Benefits of Following LSP

  1. Improved Reusability: Subclasses work seamlessly with existing code.
  2. Ease of Testing: Code that adheres to LSP is predictable and easier to test.
  3. Enhanced Maintenance: Clear boundaries between classes make debugging and extending functionality straightforward.

Conclusion

The Liskov Substitution Principle is critical for creating robust and flexible object-oriented designs. By ensuring that subclasses can be used interchangeably with their base classes without causing unexpected behavior, you build systems that are easier to maintain and extend. When designing your class hierarchies, always ask: "Can this subclass replace its base class without altering the program's behavior?"

Following LSP not only strengthens your adherence to SOLID principles but also sets the foundation for scalable and maintainable software solutions. Happy coding!

dance

Let connect on LinkedIn and checkout my GitHub repos:

Comments 13 total

  • David Au Yeung
    David Au YeungDec 19, 2024

    Thanks for reminding!

    • Aditya
      AdityaDec 20, 2024

      Thanks! if you liked the content pls give a thumbs up for upcoming articles

  • L Rodríguez
    L RodríguezDec 19, 2024

    Very good example

    • Aditya
      AdityaDec 20, 2024

      I'm glad that you liked it

  • petergsimons
    petergsimonsDec 20, 2024

    Good job explaining something relatively complex in such a nice and simple way, as someone who has interviewed a lot of developers throughout my career I can honestly say this is something people always struggle to articulate beyond reciting the "dictionary definition" during interviews

    • Aditya
      AdityaDec 23, 2024

      Thanks! I hope you like this article. Follow for more such contents

  • Riccardo richard_ekeopara_846
    Riccardo richard_ekeopara_846Dec 21, 2024

    Very good article 👍

  • João Angelo
    João AngeloDec 24, 2024

    Hi, thanks for sharing!

    • Aditya
      AdityaDec 25, 2024

      I'm glad you liked it

  • Talles L
    Talles LJan 6, 2025

    Not that I care, I think inheritance just ruins codebases anyway, but a nitpick: a square is a rectangle. The second code snippet (the solution) fails that check.

    • Aditya
      AdityaJan 9, 2025

      Agreed. But dont you think inheritance makes our lives a bit easier? We have to write a bit less code and enjoy being lazy....

      • Talles L
        Talles LJan 11, 2025

        After many years of digesting many kinds of codebases, I'm definitely a "composition over inheritance" kind of person...

        Sharing things by inheritance eventually bites you when you have to change a base behavior but just for some of the classes instead of all of them.

Add comment