// -> http://tomasp.net/blog/2015/csharp-pattern-matching/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PatternMatching { class Program { static void Main(string[] args) { var expr = new Multiply { Left = new Variable { Name = "x"}, Right = new Add { Left = new Constant { Value = 1 }, Right = new Constant { Value = 2} } }; Console.WriteLine(Format(expr)); Console.WriteLine(Evaluate(expr, new Dictionary { { "x", 4 } })); Console.ReadLine(); } public static string Format(Exception e) { try { throw e; } catch (Constant n) { return n.Value.ToString(); } catch (Variable v) { return v.Name; } catch (Add a) { return $"({Format(a.Left)} + {Format(a.Right)})"; } catch (Multiply a) { return $"{Format(a.Left)} * {Format(a.Right)}"; } } public static int Evaluate(Exception e, IDictionary vars) { int res; try { throw e; } catch (Constant n) { return n.Value; } catch (Variable v) when (vars.TryGetValue(v.Name, out res)) { return res; } catch (Variable _) { throw new ArgumentException("Variable not found!"); } catch (Add a) { return Evaluate(a.Left, vars) + Evaluate(a.Right, vars); } catch (Multiply a) { return Evaluate(a.Left, vars) + Evaluate(a.Right, vars); } } } public class Variable : Exception { public string Name { get; set; } } public class Constant : Exception { public int Value { get; set; } } public class Add : Exception { public Exception Left { get; set; } public Exception Right { get; set; } } public class Multiply : Exception { public Exception Left { get; set; } public Exception Right { get; set; } } }