Liskov Substitution Principle In C#

We will be discussing the Liskov Substitution Principle also known as LSP, as one of the SOLID principles of object-oriented programming and how to implement it when designing our software.

This principle said that Subtypes must be substitutable for their base types. In other words, if we substitute a superclass object reference with an object of any of its subclasses, the program should not break.

Example

Here we design three classes for employees and one abstract class and Implement abstract class on these classes,

  1. PermamentEmployee.cs
  2. ContractEmployee.cs
  3. TemporaryEmployee.cs
class LSP {
    public LSP() {
        Run();
    }
    public void Run() {
        Console.ReadLine();
    }
    public abstract class Employee {
        protected string FullName {
            get;
            set;
        }
        protected abstract string CalculateBonus();
    }
    public class PermamentEmployee: Employee {
        PermamentEmployee() {
            FullName = "Ashish";
        }
        protected override string CalculateBonus() {
            return "25000.00";
        }
    }
    public class ContractEmployee: Employee {
        ContractEmployee() {
            FullName = "Nirmal";
        }
        protected override string CalculateBonus() {
            return "75000.00";
        }
    }
    public class TemporaryEmployee: Employee {
        TemporaryEmployee() {
            FullName = "Sheeba";
        }
        protected override string CalculateBonus() {
            throw new NotImplementedException(); // Not Applicable LSP
        }
    }
}

The above implementation has one problem, temporary employees are not applicable for the bonus in this case. CalculateBonus () does not perform any logic but must you have to define the body of this abstract signature.

Again, Modify the code as per the LSP Principle.

 I must define one interface and implement every class which one is applicable for the bonus.

class LSP {
    public LSP() {
        Run();
    }
    public void Run() {
        Console.ReadLine();
    }
    interface IEmployee {
        public string CalculateBonus();
    }
    public abstract class Employee {
        protected string FullName {
            get;
            set;
        }
    }
    public class PermamentEmployee: Employee, IEmployee {
        PermamentEmployee() {
            FullName = "Ashish";
        }
        public string CalculateBonus() {
            return "25000.00";
        }
    }
    public class ContractEmployee: Employee, IEmployee {
        ContractEmployee() {
            FullName = "Nirmal";
        }
        public string CalculateBonus() {
            return "75000.00";
        }
    }
    public class TemporaryEmployee: Employee {
        TemporaryEmployee() {
            FullName = "Sheeba";
        }
    }
}

Conclusion

We can see that implementing the LSP is not that complicated but just the opposite. Most of us probably already implemented this principle many times in our code without knowing its name because in the object-oriented world Polymorphism is quite a big thing.