.NETMedium
What is the Liskov Substitution Principle with a real example?
LSP: subclasses must be substitutable for their base class without breaking callers.
Classic violation — Rectangle / Square:
public class Rectangle {
public virtual int Width { get; set; }
public virtual int Height { get; set; }
}
public class Square : Rectangle {
public override int Width { set => base.Width = base.Height = value; }
public override int Height { set => base.Width = base.Height = value; }
}
// Caller written against Rectangle:
void Resize(Rectangle r) {
r.Width = 10;
r.Height = 5;
Console.WriteLine(r.Width * r.Height); // expects 50
}
Resize(new Square()); // prints 25 — surprise!
The Square is a rectangle in geometry but not a rectangle in this code — its setters violate the caller's expectation that width and height move independently.
Real-world version: a ReadOnlyList<T> that inherits List<T> and overrides Add to throw NotSupportedException. Any code that takes a List<T> and calls Add will break unpredictably.
The fix: model the behaviour you support, not the taxonomy. Use IReadOnlyList<T> and IList<T> as separate interfaces; choose what to implement based on what the type actually does.