KEY POINTS
- Subtypes must be substitutable for their base types.
FIXING LSP
- Minimize null checks with c# features,guard clauses, null object design pattern
- Follow lsp and make sure to fully implement interfaces
namespace LiskovSubsPrinciple
{
public class Square : Rectangle
{
private int _height;
private int _width;
public override int Height
{
get { return _height; }
set
{
_width = value;
_height = value;
}
}
public override int Width
{
get { return _width; }
set
{
_width = value;
_height = value;
}
}
}
public class AreaCalculator
{
public static int CalculateArea(Rectangle r)
{
return r.Height * r.Width;
}
}
public class Rectangle
{
public virtual int Height { get; set; }
public virtual int Width { get; set; }
}
}
PROGRAM.CS
using LiskovSubsPrinciple;
Rectangle newRectangle = new Square();
newRectangle.Height = 4;
newRectangle.Width = 6;
Console.WriteLine(AreaCalculator.CalculateArea(newRectangle));//36
OUTPUT
36
SOLVE LSP SOLUTION - 1
namespace LiskovSubsPrinciple
{
public class AreaCalculator
{
public static int CalculateArea(Rectangle r)
{
return r.Height * r.Width;
}
public static int CalculateSquareArea(Rectangle r)
{
return r.Height * r.Height;
}
}
public class Rectangle
{
public virtual int Height { get; set; }
public virtual int Width { get; set; }
public bool IsSquare => Height == Width;
}
}
using LiskovSubsPrinciple;
Rectangle newRectangle = new ();
newRectangle.Height = 4;
newRectangle.Width = 6;
if (newRectangle.IsSquare)
{
Console.WriteLine("this is a square");
Console.WriteLine(AreaCalculator.CalculateSquareArea(newRectangle));
}
else
{
Console.WriteLine("this is a rectangle");
Console.WriteLine(AreaCalculator.CalculateArea(newRectangle));
}
SOLVE LSP SOLUTION -2
SQUARE AS SEPARATE TYPE WITHOUT HAVING DEPENDENCY ON RECTANGLE
public class Rectangle
{
public virtual int Height { get; set; }
public virtual int Width { get; set; }
}
public class Square
{
public virtual int Side { get; set; }
}