{"id":1698,"date":"2023-05-04T15:19:27","date_gmt":"2023-05-04T08:19:27","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=1698"},"modified":"2023-05-13T14:31:58","modified_gmt":"2023-05-13T07:31:58","slug":"csharp-visitor-pattern","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-visitor-pattern\/","title":{"rendered":"C# Visitor Pattern"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you will learn about the C# Visitor pattern and how to use it to add new behaviors to multiple related classes without modifying them directly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the C# Visitor pattern<\/h2>\n\n\n\n<p>The Visitor pattern is a behavioral design pattern that allows you to add new behaviors to existing <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-class\/\">classes<\/a> without modifying them. The Visitor pattern does this by separating the behaviors from the classes and moving them to separate classes called Visitor.<\/p>\n\n\n\n<p>The Visitor pattern is useful when you have a lot of related classes and want to add new behaviors to all of them. So instead of modifying each individual class separately, you can use the Visitor pattern to define the new behaviors in the Visitor classes.<\/p>\n\n\n\n<p>The following UML diagram illustrates the Visitor pattern:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/csharptutorial.net\/wp-content\/uploads\/2023\/05\/CSharp-Visitor-Design-Pattern.svg\" alt=\"C# Visitor Design Pattern\" class=\"wp-image-1707\"\/><\/figure>\n<\/div>\n\n\n<p>Here are the participants:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Element<\/code> is the <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-interface\/\">interface<\/a> or <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-abstract-class\/\">abstract class<\/a> that defines <code>Accept()<\/code> method for accepting a <code>Visitor<\/code> object.<\/li>\n\n\n\n<li><code>ElementA<\/code> and <code>ElementB<\/code> are concrete classes of the <code>Element<\/code> class or the implementations of the <code>Element<\/code> interface. They provide the actual implementation of the <code>Accept()<\/code> method. They also have their own specific methods.<\/li>\n\n\n\n<li><code>Visitor<\/code> is the interface or abstract class that defines the behavior performed on the <code>Element<\/code> objects. It defines a set of <code>Visit*<\/code> methods, each corresponding to an element type (<code>ElementA<\/code> and <code>ElementB<\/code>).<\/li>\n\n\n\n<li><code>ConcreteVisitor<\/code> is the implementation of the <code>Visitor<\/code> interface or the concrete class of the <code>Visitor<\/code> abstract class. The <code>ConcreteVisitor<\/code> class provides the actual implementation of the <code>Visit*<\/code> methods for each element.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">C# Visitor pattern example<\/h2>\n\n\n\n<p>Suppose you have the <code>Employee<\/code> class as the base class of the <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> classes. The <code>Employee<\/code> class has two properties, <code>Name<\/code> and <code>Salary<\/code>. <\/p>\n\n\n\n<p>The <code><code>BackOfficeEmployee<\/code><\/code> class adds a new property, <code>Bonus<\/code> while the <code><code>SalesEmployee<\/code><\/code> class has another new property, <code>Commission<\/code>.<\/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\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Employee<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> Name { <span class=\"hljs-keyword\">get<\/span>;  <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Salary { <span class=\"hljs-keyword\">get<\/span>;  <span class=\"hljs-keyword\">set<\/span>; }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Employee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary<\/span>)<\/span>\n    {\n        Name = name;\n        Salary = salary;\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BackOfficeEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Bonus {   <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">BackOfficeEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> bonus<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Bonus = bonus;\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SalesEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Commission { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">SalesEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> commission<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Commission = commission;\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>Imagine that you need to calculate the total compensation of all employees. To do that, you can add the <code>GetTotalCompensation<\/code> method to both <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> classes.<\/p>\n\n\n\n<p>The total compensation of the <code>BackOfficeEmployee<\/code> would be the sum of their salary and bonus, while the total compensation of <code>SalesEmployee<\/code> would be the sum of their salary and commission.<\/p>\n\n\n\n<p>Later, you need to calculate the stock options that both <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code>  can get. To do so, you may add another method called <code>GetStockOptions<\/code> to both classes.<\/p>\n\n\n\n<p>Doing this violates the <a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-open-closed-principle\/\">open-closed principle<\/a> because the class should be open for extension and closed for modification. <\/p>\n\n\n\n<p>It will also violate the <a href=\"https:\/\/csharptutorial.net\/csharp-design-patterns\/csharp-single-responsibility-principle\/\">single responsibility principle<\/a> because <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> classes are not only the representations of the Back Office Employee and Sales Employee but are also in charge of calculating the total compensation and stock options.<\/p>\n\n\n\n<p>To resolve this, you can use the Visitor pattern as described in the following UML diagram:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/csharptutorial.net\/wp-content\/uploads\/2023\/05\/CSharp-Visitor-Pattern-Example.svg\" alt=\"C# Visitor Pattern Example\" class=\"wp-image-1706\"\/><\/figure>\n\n\n\n<p>The following program illustrates how to use the Visitor pattern for adding compensation and stock option calculation function:<\/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\">namespace<\/span> <span class=\"hljs-title\">VisitorPattern<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/span>;\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/span>;\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Employee<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> Name { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Salary { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Employee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary<\/span>)<\/span>\n    {\n        Name = name;\n        Salary = salary;\n    }\n\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BackOfficeEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>, <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Bonus { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;}\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">BackOfficeEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> bonus<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Bonus = bonus;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/span> =&gt; visitor.Visit(<span class=\"hljs-keyword\">this<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SalesEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>, <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Commission { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">SalesEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> commission<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Commission = commission;\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/span> =&gt; visitor.Visit(<span class=\"hljs-keyword\">this<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CompensationVisitor<\/span> : <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> TotalCompensation { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">set<\/span>; } = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>\n    {\n        TotalCompensation += e.Salary + e.Bonus;\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/span>\n    {\n        TotalCompensation += e.Salary + e.Commission;\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">EmployeeStockOptionVisitor<\/span> : <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> TotalUnit { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">set<\/span>; } = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> totalCompensation = e.Salary + e.Bonus;\n        TotalUnit += totalCompensation &gt; <span class=\"hljs-number\">100000<\/span> ? <span class=\"hljs-number\">1000<\/span> : <span class=\"hljs-number\">500<\/span>;\n\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> totalCompensation = e.Salary + e.Commission;\n        TotalUnit += totalCompensation &gt; <span class=\"hljs-number\">100000<\/span> ? <span class=\"hljs-number\">1000<\/span> : <span class=\"hljs-number\">500<\/span>;\n    }\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\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> employees = <span class=\"hljs-keyword\">new<\/span> List&lt;IVisitableElement&gt;\n        {\n            <span class=\"hljs-keyword\">new<\/span> BackOfficeEmployee(<span class=\"hljs-string\">\"John\"<\/span>,<span class=\"hljs-number\">80000<\/span>,<span class=\"hljs-number\">10000<\/span>),\n            <span class=\"hljs-keyword\">new<\/span> BackOfficeEmployee(<span class=\"hljs-string\">\"Jane\"<\/span>,<span class=\"hljs-number\">120000<\/span>,<span class=\"hljs-number\">10000<\/span>),\n            <span class=\"hljs-keyword\">new<\/span> SalesEmployee(<span class=\"hljs-string\">\"Bob\"<\/span>,<span class=\"hljs-number\">90000<\/span>,<span class=\"hljs-number\">40000<\/span>),\n        };\n\n        <span class=\"hljs-comment\">\/\/ Calculating total compensation<\/span>\n        <span class=\"hljs-keyword\">var<\/span> compensationVisitor = <span class=\"hljs-keyword\">new<\/span> CompensationVisitor();\n\n        employees.ForEach(e =&gt; e.Accept(compensationVisitor));\n        Console.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{compensationVisitor.TotalCompensation:C}<\/span>\"<\/span>);\n\n\n        <span class=\"hljs-comment\">\/\/ Calculating total stock options<\/span>\n        <span class=\"hljs-keyword\">var<\/span> esoVisitor = <span class=\"hljs-keyword\">new<\/span> EmployeeStockOptionVisitor();\n        employees.ForEach(e =&gt; e.Accept(esoVisitor));\n\n        Console.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{esoVisitor.TotalUnit}<\/span>\"<\/span>);\n\n    }\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>How it works.<\/p>\n\n\n\n<p>First, define the <code>IVisitableElement<\/code> interface that has the <code>Accept()<\/code> method with an <code>IVisitor<\/code> argument:<\/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\">interface<\/span> <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/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>Second, define the <code>IVisitor<\/code> interface that has two <code>Visit<\/code> methods, each accepting the <code>BackOfficeEmployee<\/code> or <code>SalesEmployee<\/code> object respectively:<\/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\">interface<\/span> <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/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>Third, implement the <code>IVisitableElement<\/code> interface from the <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> classes:<\/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\">BackOfficeEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>, <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Bonus { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;}\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">BackOfficeEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> bonus<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Bonus = bonus;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/span> =&gt; visitor.Visit(<span class=\"hljs-keyword\">this<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SalesEmployee<\/span> : <span class=\"hljs-title\">Employee<\/span>, <span class=\"hljs-title\">IVisitableElement<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Commission { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">SalesEmployee<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> name, <span class=\"hljs-keyword\">decimal<\/span> salary, <span class=\"hljs-keyword\">decimal<\/span> commission<\/span>) : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">name, salary<\/span>)<\/span>\n    {\n        Commission = commission;\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Accept<\/span>(<span class=\"hljs-params\">IVisitor visitor<\/span>)<\/span> =&gt; visitor.Visit(<span class=\"hljs-keyword\">this<\/span>);\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>Fourth, define the <code>CompensationVisitor<\/code> that implements the <code>IVisitor<\/code> interface. The <code>Visit*<\/code> methods calculate the total compensation of the <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> objects:<\/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\">CompensationVisitor<\/span> : <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> TotalCompensation { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">set<\/span>; } = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>\n    {\n        TotalCompensation += e.Salary + e.Bonus;\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/span>\n    {\n        TotalCompensation += e.Salary + e.Commission;\n    }\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>Fifth, define the <code>EmployeeStockOptionVisitor<\/code> that implements <code>IVisitor<\/code> interface. The <code>Visit()<\/code> methods calculate the total stock options unit needed:<\/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\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">EmployeeStockOptionVisitor<\/span> : <span class=\"hljs-title\">IVisitor<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> TotalUnit { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">set<\/span>; } = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">BackOfficeEmployee e<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> totalCompensation = e.Salary + e.Bonus;\n        TotalUnit += totalCompensation &gt; <span class=\"hljs-number\">100000<\/span> ? <span class=\"hljs-number\">1000<\/span> : <span class=\"hljs-number\">500<\/span>;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Visit<\/span>(<span class=\"hljs-params\">SalesEmployee e<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> totalCompensation = e.Salary + e.Commission;\n        TotalUnit += totalCompensation &gt; <span class=\"hljs-number\">100000<\/span> ? <span class=\"hljs-number\">1000<\/span> : <span class=\"hljs-number\">500<\/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<p>Finally, create a list of <code>IVisitableElement<\/code> objects including both <code>BackOfficeEmployee<\/code> and <code>SalesEmployee<\/code> and use the <code>CompensationVisitor<\/code> and <code>EmployeeStockOptionVisitor<\/code> to calculate the total compensation and stock options:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" 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\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n\n        <span class=\"hljs-keyword\">var<\/span> employees = <span class=\"hljs-keyword\">new<\/span> List&lt;IVisitableElement&gt;\n        {\n            <span class=\"hljs-keyword\">new<\/span> BackOfficeEmployee(<span class=\"hljs-string\">\"John\"<\/span>,<span class=\"hljs-number\">80000<\/span>,<span class=\"hljs-number\">10000<\/span>),\n            <span class=\"hljs-keyword\">new<\/span> BackOfficeEmployee(<span class=\"hljs-string\">\"Jane\"<\/span>,<span class=\"hljs-number\">120000<\/span>,<span class=\"hljs-number\">10000<\/span>),\n            <span class=\"hljs-keyword\">new<\/span> SalesEmployee(<span class=\"hljs-string\">\"Bob\"<\/span>,<span class=\"hljs-number\">90000<\/span>,<span class=\"hljs-number\">40000<\/span>),\n        };\n\n        <span class=\"hljs-comment\">\/\/ Calculating total compensation<\/span>\n        <span class=\"hljs-keyword\">var<\/span> compensationVisitor = <span class=\"hljs-keyword\">new<\/span> CompensationVisitor();\n        employees.ForEach(e =&gt; e.Accept(compensationVisitor));\n\n        Console.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{compensationVisitor.TotalCompensation:C}<\/span>\"<\/span>);\n\n\n        <span class=\"hljs-comment\">\/\/ Calculating total stock options<\/span>\n        <span class=\"hljs-keyword\">var<\/span> esoVisitor = <span class=\"hljs-keyword\">new<\/span> EmployeeStockOptionVisitor();\n        employees.ForEach(e =&gt; e.Accept(esoVisitor));\n\n        Console.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{esoVisitor.TotalUnit}<\/span>\"<\/span>);\n\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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>Use the Visitor pattern to add new behavior to a group of related classes without modifying them directly.<\/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=\"1698\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-visitor-pattern\/\"\n\t\t\t\tdata-post-title=\"C# Visitor Pattern\"\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=\"1698\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-visitor-pattern\/\"\n\t\t\t\tdata-post-title=\"C# Visitor Pattern\"\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 will learn about the C# Visitor pattern and how to use it to add new behaviors to a large number of related classes without modifying them directly.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1441,"menu_order":27,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1698","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1698","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=1698"}],"version-history":[{"count":5,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1698\/revisions"}],"predecessor-version":[{"id":1812,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1698\/revisions\/1812"}],"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=1698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}