Last active
July 7, 2020 12:21
-
-
Save vasilkosturski/55e6297175b5070df2ced49b07d880b5 to your computer and use it in GitHub Desktop.
clash-of-styles-double-dispatch
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 DoubleDispatch | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var expression = new Addition( | |
new MyInt(3), | |
new Addition(new MyRational(2, 3), new MyInt(5))); | |
var asString = expression.Stringify(); | |
var result = expression.Eval(); | |
Console.WriteLine($"{asString} = {result.Stringify()}"); // 3 + 2/3 + 5 = 26/3 | |
} | |
} | |
public interface IExpression | |
{ | |
IValue Eval(); | |
string Stringify(); | |
} | |
public interface IValue : IExpression | |
{ | |
IValue AddValue(IValue operand); | |
IValue AddInt(MyInt operand); | |
IValue AddRational(MyRational operand); | |
} | |
public class MyInt : IValue | |
{ | |
public int Val { get; } | |
public MyInt(int val) | |
{ | |
Val = val; | |
} | |
public IValue Eval() => this; | |
public string Stringify() => Val.ToString(); | |
public IValue AddValue(IValue operand) => operand.AddInt(this); | |
public IValue AddInt(MyInt operand) => new MyInt(Val + operand.Val); | |
public IValue AddRational(MyRational operand) | |
=> new MyRational(operand.Numerator + operand.Denominator * Val, operand.Denominator); | |
} | |
public class MyRational : IValue | |
{ | |
public int Numerator { get; } | |
public int Denominator { get; } | |
public MyRational(int numerator, int denominator) | |
{ | |
Numerator = numerator; | |
Denominator = denominator; | |
} | |
public IValue Eval() => this; | |
public string Stringify() => $"{Numerator}/{Denominator}"; | |
public IValue AddValue(IValue operand) | |
=> operand.AddRational(this); | |
public IValue AddInt(MyInt operand) | |
=> operand.AddRational(this); | |
public IValue AddRational(MyRational operand) | |
{ | |
return new MyRational( | |
Numerator * operand.Denominator + operand.Numerator * Denominator, | |
Denominator * operand.Denominator); | |
} | |
} | |
public class Addition : IExpression | |
{ | |
private readonly IExpression _operand1; | |
private readonly IExpression _operand2; | |
public Addition(IExpression operand1, IExpression operand2) | |
{ | |
_operand1 = operand1; | |
_operand2 = operand2; | |
} | |
public IValue Eval() => _operand1.Eval().AddValue(_operand2.Eval()); | |
public string Stringify() => $"{_operand1.Stringify()} + {_operand2.Stringify()}"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment