using System.Collections.Generic;
public static void Main()
Element element = new MultiCompositeElement(
new BinaryCompositeElement(
new LeafElementA(), new LeafElementA()),
Console.WriteLine("element before: \r\n" + element.ToString());
IVisitor visitor = new AToBVisitor();
visitor = new AddOneMoreVisitor();
Console.WriteLine("element after: \r\n" + element.ToString());
public abstract class Element
internal abstract Element Accept(IVisitor visitor);
public interface IVisitor
Element Visit(Element element);
Element VisitNonRecursive(Element element);
Element VisitNonRecursive(LeafElementA leafElementA);
Element VisitNonRecursive(LeafElementB leafElementB);
Element VisitNonRecursive(MultiCompositeElement multiCompositeElement);
Element VisitNonRecursive(BinaryCompositeElement binaryCompositeElement);
public abstract class VisitorBase: IVisitor
public virtual Element Visit(Element element)
element = element.Accept(this);
public virtual Element VisitNonRecursive(Element element)
public virtual Element VisitNonRecursive(LeafElementA leafElementA)
return VisitNonRecursive(leafElementA as Element);
public virtual Element VisitNonRecursive(LeafElementB leafElementB)
return VisitNonRecursive(leafElementB as Element);
public virtual Element VisitNonRecursive(MultiCompositeElement multiCompositeElement)
return VisitNonRecursive(multiCompositeElement as Element);
public virtual Element VisitNonRecursive(BinaryCompositeElement binaryCompositeElement)
return VisitNonRecursive(binaryCompositeElement as Element);
public class LeafElementA : Element
internal override Element Accept(IVisitor visitor)
return visitor.VisitNonRecursive(this);
public override string ToString() {
public class LeafElementB : Element
internal override Element Accept(IVisitor visitor)
return visitor.VisitNonRecursive(this);
public override string ToString() {
public class BinaryCompositeElement : Element
public BinaryCompositeElement(Element left, Element right)
public Element Left { get; private set; }
public Element Right { get; private set; }
internal override Element Accept(IVisitor visitor)
Left = visitor.Visit(Left);
Right = visitor.Visit(Right);
return visitor.VisitNonRecursive(this);
public override string ToString() {
return "BinaryCompositeElement[\r\nLeft = " + Left + "\r\nRight = " + Right + "\r\n]";
public class MultiCompositeElement : Element
public MultiCompositeElement(params Element[] containedElements)
ContainedElements = containedElements.ToList();
public ICollection<Element> ContainedElements { get; private set; }
internal override Element Accept(IVisitor visitor)
ContainedElements = ContainedElements
return visitor.VisitNonRecursive(this);
public override string ToString() {
string children = string.Join(", ", ContainedElements);
return "MultiCompositeElement[\r\nContainedElements = [\r\n " + children + "\r\n ]\r\n]";
public class AddOneMoreVisitor : VisitorBase
public override Element VisitNonRecursive(MultiCompositeElement multiCompositeElement)
multiCompositeElement.ContainedElements.Add(new LeafElementA());
return multiCompositeElement;
public override Element VisitNonRecursive(BinaryCompositeElement binaryCompositeElement)
var result = new MultiCompositeElement(
binaryCompositeElement.Left,
binaryCompositeElement.Right,
public class AToBVisitor : VisitorBase
public override Element VisitNonRecursive (LeafElementA leafElementA)
return new LeafElementB();