public static void Main()
Console.WriteLine(new DogSignTextBuilder().BuildSignText(new Dog("Fido")));
public interface IAnimalVisitor<out T>
T Accept<T>(IAnimalVisitor<T> v);
public abstract class AnimalBase : IAnimal
public string Name { get; set;}
protected AnimalBase(string name)
public abstract T Accept<T>(IAnimalVisitor<T> v);
public class Dog : AnimalBase
public Dog(string name) : base(name) { }
public override T Accept<T>(IAnimalVisitor<T> v)
public class Cat : AnimalBase
public Cat(string name) : base(name) { }
public override T Accept<T>(IAnimalVisitor<T> v)
public class AnimalSpeaker
private class SpeakerVisitor : IAnimalVisitor<string>
public string Visit(Dog a)
public string Visit(Cat a)
private readonly SpeakerVisitor _SpeakerVisitor = new SpeakerVisitor();
public string Speak(IAnimal a)
return a.Accept(_SpeakerVisitor);
public abstract class AnimalSignTextBuilderBase<TAnimal>
private readonly AnimalSpeaker _AnimalSpeaker = new AnimalSpeaker();
public string BuildSignText(TAnimal a)
var spokenText = _AnimalSpeaker.Speak(a);
return string.Format("{0} says {1}.",a.Name, spokenText);
public class DogSignTextBuilder : AnimalSignTextBuilderBase<Dog> { }
public class CatSignTextBuilder : AnimalSignTextBuilderBase<Cat> { }