Skip to content

Instantly share code, notes, and snippets.

@vasilkosturski
Last active August 9, 2020 07:32
Show Gist options
  • Save vasilkosturski/79d68cdaca7a1cef1471e1f9ccdc0877 to your computer and use it in GitHub Desktop.
Save vasilkosturski/79d68cdaca7a1cef1471e1f9ccdc0877 to your computer and use it in GitHub Desktop.
clash-of-styles-the-visitor
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