C# › Interfaces & Abstract Classes
How would you implement the 'Liskov Substitution Principle' correctly when designing an abstract class hierarchy, and what's a classic violation example?
AdvancedAnswer
LSP requires that any subclass must be fully usable anywhere its base class is expected, WITHOUT breaking the caller's expectations — a classic violation is a 'Square extends Rectangle' hierarchy where setting Square's Width also changes its Height (to stay square), silently breaking code that assumes setting Rectangle.Width leaves Height unaffected.
public class Rectangle {
public virtual double Width { get; set; }
public virtual double Height { get; set; }
}
public class Square : Rectangle {
public override double Width { get => base.Width; set { base.Width = value; base.Height = value; } } // LSP violation!
}
// Code assuming 'rect.Width = 5' doesn't affect Height breaks silently for a SquareReal-world example Recognizing and avoiding a classic LSP violation when a seemingly natural 'is-a' relationship (Square is-a Rectangle) breaks behavioral expectations.