Last active
August 9, 2020 07:32
-
-
Save vasilkosturski/79d68cdaca7a1cef1471e1f9ccdc0877 to your computer and use it in GitHub Desktop.
clash-of-styles-the-visitor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace Visitor | |
{ | |
class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var expression = new Addition( | |
new MyInt(1), | |
new Addition(new MyInt(0), new MyInt(5))); | |
var visitor = new CountZerosVisitor(); | |
var numberOfZeroes = expression.Accept(visitor); | |
// Output: "The expression 1 + 0 + 5 has 1 zeroes." | |
Console.WriteLine($"The expression {expression.Stringify()} has {numberOfZeroes} zeroes."); | |
} | |
} | |
public interface IExpression | |
{ | |
int Eval(); | |
string Stringify(); | |
T Accept<T>(IVisitor<T> visitor); | |
} | |
public class MyInt : IExpression | |
{ | |
public int Val { get; } | |
public MyInt(int val) | |
{ | |
Val = val; | |
} | |
public int Eval() => Val; | |
public string Stringify() => Val.ToString(); | |
public T Accept<T>(IVisitor<T> visitor) => visitor.Visit(this); | |
} | |
public class Addition : IExpression | |
{ | |
public IExpression Operand1 { get; } | |
public IExpression Operand2 { get; } | |
public Addition(IExpression operand1, IExpression operand2) | |
{ | |
Operand1 = operand1; | |
Operand2 = operand2; | |
} | |
public int Eval() => Operand1.Eval() + Operand2.Eval(); | |
public string Stringify() => $"{Operand1.Stringify()} + {Operand2.Stringify()}"; | |
public T Accept<T>(IVisitor<T> visitor) => visitor.Visit(this); | |
} | |
public interface IVisitor<out T> | |
{ | |
T Visit(MyInt integer); | |
T Visit(Addition addition); | |
} | |
public class CountZerosVisitor : IVisitor<int> | |
{ | |
public int Visit(MyInt integer) => integer.Val == 0 ? 1 : 0; | |
public int Visit(Addition addition) => | |
addition.Operand1.Accept(this) + addition.Operand2.Accept(this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment