title: Using the visitor pattern with generics in C#
body: <p>I want to know whether the below is an acceptable use of the visitor pattern. I feel a little uncomfortable returning from an Accept() or Visit() call - is this an appropriate usage of this pattern and if not, why not?</p>
  
  <p><strong>Note:</strong> Apologies for the long code sample, seems necessary to get across what I'm doing as visitor always seems to be a little involved...</p>
  
  <pre><code>interface IAnimalElement&lt;T&gt;
  {
     T Accept(IAnimalVisitor&lt;T&gt; visitor);
  }
  
  interface IAnimalVisitor&lt;T&gt;
  {
      T Visit(Lion lion);
      T Visit(Peacock peacock);
      T VisitZoo(List&lt;Animal&gt; animals);
  }
  
  abstract class Animal
  {
      public int Age { get; protected set; }
  }
  
  class Lion : Animal, IAnimalElement&lt;int&gt;
  {
      public Lion(int age)
      {
          Age = age;
      }
  
      public int Accept(IAnimalVisitor&lt;int&gt; visitor)
      {
          return visitor.Visit(this);
      }
  }
  
  class Peacock : Animal, IAnimalElement&lt;int&gt;
  {
      public Peacock(int age)
      {
          Age = age;
      }
  
      public int Accept(IAnimalVisitor&lt;int&gt; visitor)
      {
          return visitor.Visit(this);
      }
  }
  
  class AnimalAgeVisitor : IAnimalVisitor&lt;int&gt;
  {
      public int TotalAge { get; private set; }
  
      int IAnimalVisitor&lt;int&gt;.Visit(Lion lion)
      {
          TotalAge += lion.Age;
          return lion.Age;
      }
  
      int IAnimalVisitor&lt;int&gt;.Visit(Peacock peacock)
      {
          TotalAge += peacock.Age + 10;
          return peacock.Age + 10; // peacocks ages are always -10y, correct.
      }
  
      public int VisitZoo(List&lt;Animal&gt; animals)
      {
          // Calculate average animal age.
  
          int sum = 0;
          int count = 0;
          foreach (IAnimalElement&lt;int&gt; animal in animals)
          {
              sum += animal.Accept(this);
              ++count;
          }
  
          return count == 0 ? 0 : sum / count;
      }
  }
  
  class Program
  {
      static void Main(string[] args)
      {
          List&lt;Animal&gt; animals = new List&lt;Animal&gt;() { new Lion(10), 
            new Lion(15), new Peacock(3), new Lion(2), new Peacock(9) };
  
          AnimalAgeVisitor visitor = new AnimalAgeVisitor();
  
          Console.WriteLine("Average age = {0}, Total age = {1}", 
              visitor.VisitZoo(animals), visitor.TotalAge);
      }
  }
  </code></pre>