{"id":1461,"date":"2023-04-10T10:34:36","date_gmt":"2023-04-10T03:34:36","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=1461"},"modified":"2024-12-14T22:36:17","modified_gmt":"2024-12-14T15:36:17","slug":"csharp-liskov-substitution-principle","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-liskov-substitution-principle\/","title":{"rendered":"C# Liskov Substitution Principle"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about the C# Liskov substitution principle and how to apply it to build more scalable and maintainable software applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the C# Liskov Substitution Principle<\/h2>\n\n\n\n<p>The Liskove substitution principle (LSP) is the third principle in the SOLID principles of object-oriented design:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-single-responsibility-principle\/\">Single Responsibility Principle (SRP)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-open-closed-principle\/\">Open-Closed Principle (OCP)<\/a><\/li>\n\n\n\n<li><strong>Liskov Substitution Principle (LSP)<\/strong><\/li>\n\n\n\n<li><a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-interface-segregation-principle\/\">Interface Segregation Principle (ISP)&nbsp;<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-dependency-inversion-principle\/\">Dependency Inversion Principle (DIP)<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"note\">Note that the Liskov substitution principle is named after <a href=\"https:\/\/en.wikipedia.org\/wiki\/Liskov_substitution_principle\" target=\"_blank\" rel=\"noreferrer noopener\">Barbara Liskov<\/a>, who formulated it in 1988.<\/p>\n\n\n\n<p>The Liskov substitution principle states that if a method uses a base <a target=\"_blank\" href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-inheritance\/\" rel=\"noreferrer noopener\">class<\/a>, it should be able to use any derived classes without needing information about the derived class.<\/p>\n\n\n\n<p>In other words, the derived classes should be substitutable for their base class without causing errors or side effects. It means that the behavior of the derived class should not contradict the behavior of the base class.<\/p>\n\n\n\n<p>Let&#8217;s take an example to understand the Liskov substitution principle in C#:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">LSP<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Car<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a car\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Truck<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a truck\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">TestDrive<\/span>(<span class=\"hljs-params\">Vehicle vehicle<\/span>)<\/span>\n    {\n        vehicle.Drive();\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> car = <span class=\"hljs-keyword\">new<\/span> Car();\n        TestDrive(car);\n\n        <span class=\"hljs-keyword\">var<\/span> truck = <span class=\"hljs-keyword\">new<\/span> Truck();\n        TestDrive(truck);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define an <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-abstract-class\/\">abstract class<\/a> <code>Vehicle<\/code> that has a <code>Drive()<\/code> abstract method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, define the <code>Car<\/code> and <code>Truck<\/code> classes inherited from the <code>Vehicle<\/code> class. The <code>Drive()<\/code> method in each class displays a message in the console:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Car<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a car\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Truck<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a truck\"<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, define the <code>TestDrive()<\/code> static method in the <code>Program<\/code> class that takes a <code>Vehicle<\/code> as the parameter. The <code>TestDrive()<\/code> static method calls the <code>Drive()<\/code> method of the vehicle object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">TestDrive<\/span>(<span class=\"hljs-params\">Vehicle vehicle<\/span>)<\/span>\n    {\n        vehicle.Drive();\n    }\n    \n   <span class=\"hljs-comment\">\/\/ ...<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, pass an instance of a <code>Car<\/code> class to the <code>TestDrive()<\/code> static method, which calls the <code>Drive()<\/code> method of the <code>Car<\/code> object. Similarly, pass an instance of the <code>Truck<\/code> class to the <code>TestDrive()<\/code> static method, which calls the <code>Drive()<\/code> method of the <code>truck<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-comment\">\/\/ ...<\/span>\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> car = <span class=\"hljs-keyword\">new<\/span> Car();\n        TestDrive(car);\n\n        <span class=\"hljs-keyword\">var<\/span> truck = <span class=\"hljs-keyword\">new<\/span> Truck();\n        TestDrive(truck);\n        \n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This is an example of the Liskov substitution principle in action. We are able to use the <code>Car<\/code> and <code>Truck<\/code> objects in the <code>TestDrive()<\/code> method without causing any errors. <\/p>\n\n\n\n<p>In other words, we can substitute the derived classes (<code>Car<\/code> &amp; <code>Truck<\/code>) for their base class (<code>Vehicle<\/code>) in the <code>TestDrive()<\/code> method.<\/p>\n\n\n\n<p>Now, let&#8217;s violate the Liskov substitution principle by introducing a new derived class called <code>Aircraft<\/code>. Since you can only fly an aircraft, not drive it, the <code>Drive()<\/code> method in the <code>Aircraft<\/code> class raises an exception <code>NotImplementedException<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Aircraft<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> NotImplementedException();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When we pass an instance of the <code>Aircraft<\/code> object to the <code>TestDrive()<\/code> method, it creates a side effect (or an exception)<\/p>\n\n\n\n<p>It violates the Liskov substitution principle because we cannot substitute the <code>Aircraft<\/code> for its base class <code>Vehicle<\/code> in the <code>TestDrive()<\/code> method.<\/p>\n\n\n\n<p>The following shows the whole program that violates the Liskov substitution principle:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">LSP<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Car<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a car\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Truck<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; Console.WriteLine(<span class=\"hljs-string\">\"Drive a truck\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Aircraft<\/span> : <span class=\"hljs-title\">Vehicle<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Drive<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> NotImplementedException();\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">TestDrive<\/span>(<span class=\"hljs-params\">Vehicle vehicle<\/span>)<\/span>\n    {\n        vehicle.Drive();\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> car = <span class=\"hljs-keyword\">new<\/span> Car();\n        TestDrive(car);\n\n        <span class=\"hljs-keyword\">var<\/span> truck = <span class=\"hljs-keyword\">new<\/span> Truck();\n        TestDrive(truck);\n\n        \n        <span class=\"hljs-keyword\">var<\/span> aircraft = <span class=\"hljs-keyword\">new<\/span> Aircraft();\n        TestDrive(aircraft); <span class=\"hljs-comment\">\/\/ side effect<\/span>\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Liskov Substitution principle states that derived classes should be substitutable for their base class without causing errors.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"1461\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-liskov-substitution-principle\/\"\n\t\t\t\tdata-post-title=\"C# Liskov Substitution Principle\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"1461\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-liskov-substitution-principle\/\"\n\t\t\t\tdata-post-title=\"C# Liskov Substitution Principle\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to use the C# Liskov substitution principle to build more scalable and maintainable software applications.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1441,"menu_order":2,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1461","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1461","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/comments?post=1461"}],"version-history":[{"count":5,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1461\/revisions"}],"predecessor-version":[{"id":2708,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1461\/revisions\/2708"}],"up":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1441"}],"wp:attachment":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/media?parent=1461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}