Chapter 14: Generics and Collections

Quiz

Solution to Question 14–1.

Indexers are unnamed. You use the this keyword to create an indexer:

public string this[int index]
Solution to Question 14–2.

Any type can be used, although it’s most common to use integers.

Solution to Question 14–3.

The elements of the array must implement IComparable.

Solution to Question 14–4.

Generics allow you to create type-safe collections without specifying the type the collection will hold when you create the collection.

Solution to Question 14–5.

It allows your collection to support a foreach loop.

Solution to Question 14–6.

The size of an array is fixed when you create it. A List<T> expands dynamically when you add more elements.

Solution to Question 14–7.

A List is like an expandable array. A Stack is a “Last In, First Out” collection, a Queue is a “First In, First Out” collection, and a Dictionary is a collection of key/value pairs where you can retrieve the value given a key.

Exercises

Solution to Exercise 14-1.

Create an abstract Animal class that has private members weight and name, and abstract methods Speak( ), Move( ), and ToString( ). Derive from Animal a Cat and Dog class that override the methods appropriately. Create an Animal array, populate it with Dogs and Cats, and then call each member’s overridden virtual method.

using System;

abstract public class Animal
{
   protected int weight;
   protected string name;
   public Animal(int weight, string name)
   {
      this.weight = weight;
      this.name = name;
   }
   abstract public  void Speak(  );
   abstract public  void Move(  );
   public override string  ToString(  )
   {
      throw new Exception("The method or operation is not implemented.");
   }
}

public class Dog : Animal
{
   private string breed;

   public string Breed
   {
      get { return breed; }
      set { breed = value; }
   }
   public Dog (int weight, string name, string breed):
   base(weight,name)
   {
      this.breed = breed;
   }

   public override void Speak(  )
   {  Console.WriteLine ("Woof"); }

   public override void Move (  )
   { Console.WriteLine ("Run, run, run, drool.");  }

   public override string  ToString(  )
   {
      return "My name is " + this.name + " I weigh " + this.weight +
      " and I am a " + this.breed + "
";
   }
}



public class Cat : Animal
{

   public Cat (int weight, string name):
   base(weight,name)
   {}

   public override void Speak(  )
   {  Console.WriteLine ("Meow"); }

   public override void Move (  )
   { Console.WriteLine ("Run, tumble, nap.");  }

   public override string ToString(  )
   {
      return "My name is " + this.name + " I weigh " + this.weight +
      " and I know how to purr!
";
   }

   public void Purr(  )
   {
      Console.WriteLine("Purrrrrrrrrrrrrrrrrrrrrrrrrr
");
   }

}

public class Tester
{
   static void Main(  )
   {
      Animal[] myAnimals = new Animal[5];
      myAnimals[0] = new Dog( 72, "Milo", "Golden" );
      myAnimals[1] = new Cat( 12, "Shakespeare");
      myAnimals[2] = new Cat( 10, "Allegra");
      myAnimals[3] = new Dog( 50, "Dingo", "mixed breed" );
      myAnimals[4] = new Dog( 20, "Brandy", "Beagle" );

      foreach ( Animal a in myAnimals )
      {
         a.Speak(  );
         a.Move(  );
         Console.WriteLine(a);

         Cat c = a as Cat;  // cast to cat
         if ( c != null )   // if it is a cat
         {
            c.Purr(  );      // only cats purr
         }
      }
   }

}
Solution to Exercise 14-2.

Replace the array in Exercise 14-1 with a List. Sort the animals by size. You can simplify by just calling ToString( ) before and after the sort. Remember that you’ll need to implement IComparable.

using System;
using System.Collections.Generic;

abstract public class Animal : IComparable
{
   protected int weight;
   protected string name;

   public Animal(int weight, string name)
   {
      this.weight = weight;
      this.name = name;
   }
   abstract public  void Speak(  );
   abstract public  void Move(  );

   public override string  ToString(  )
   {
       throw new Exception("The method or operation is not implemented.");
   }

   public int CompareTo( Object rhs )
   {
      Animal otherAnimal = rhs as Animal;
      if ( otherAnimal != null )
      {
         return this.weight.CompareTo( otherAnimal.weight );
      }
      else
      {
         throw new ApplicationException("Expected to compare animals");
      }
   }
}

public class Dog : Animal
{
   private string breed;

   public string Breed
   {
      get { return breed; }
      set { breed = value; }
   }
   public Dog (int weight, string name, string breed):
   base(weight,name)
   {
      this.breed = breed;
   }

   public override void Speak(  )
   {  Console.WriteLine ("Woof"); }

   public override void Move (  )
   { Console.WriteLine ("Run, run, run, drool.");  }

   public override string  ToString(  )
   {
      return "My name is " + this.name + " I weigh " + this.weight +
      " and I am a " + this.breed ;
   }
}

public class Cat : Animal
{

   public Cat (int weight, string name):
   base(weight,name)
   {}

   public override void Speak(  )
   {  Console.WriteLine ("Meow"); }

   public override void Move (  )
   { Console.WriteLine ("Run, tumble, nap.");  }

   public override string ToString(  )
   {
      return "My name is " + this.name + " I weigh " + this.weight +
      " and I know how to purr!";
   }

   public void Purr(  )
   {
      Console.WriteLine("Purrrrrrrrrrrrrrrrrrrrrrrrrr
");
   }
}

public class Tester
{
   static void Main(  )
   {
      List<Animal> myAnimals = new List<Animal>(  );
      myAnimals.Add(new Dog( 72, "Milo", "Golden" ));
      myAnimals.Add(new Cat( 12, "Shakespeare"));
      myAnimals.Add(new Cat( 10, "Allegra"));
      myAnimals.Add(new Dog( 50, "Dingo", "mixed breed" ));
      myAnimals.Add(new Dog( 20, "Brandy", "Beagle" ));

      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine(a);
      }

      Console.WriteLine( "
After sorting by size..." );
      myAnimals.Sort(  );
      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine( a );
      }
   }
}
Solution to Exercise 14-3.

Replace the list from Exercise 14-2 with both a Stack and a Queue, and see the difference in the order in which the animals are returned.

The animal definitions are unchanged; the Tester class has the changes:

Using System.Collections.Generic;

public class Tester
{
   static void Main(  )
   {
      Console.WriteLine(
        "Adding in the order: Milo, Shakespeare, Allegra, Dingo, Brandy" );

      Stack<Animal> myStackOfAnimals = new Stack<Animal>(  );
      myStackOfAnimals.Push( new Dog( 72, "Milo", "Golden" ) );
      myStackOfAnimals.Push( new Cat( 12, "Shakespeare" ) );
      myStackOfAnimals.Push( new Cat( 10, "Allegra" ) );
      myStackOfAnimals.Push( new Dog( 50, "Dingo", "mixed breed" ) );
      myStackOfAnimals.Push( new Dog( 20, "Brandy", "Beagle" ) );

      Queue<Animal> myQueueOfAnimals = new Queue<Animal>(  );
      myQueueOfAnimals.Enqueue( new Dog( 72, "Milo", "Golden" ) );
      myQueueOfAnimals.Enqueue( new Cat( 12, "Shakespeare" ) );
      myQueueOfAnimals.Enqueue( new Cat( 10, "Allegra" ) );
      myQueueOfAnimals.Enqueue( new Dog( 50, "Dingo", "mixed breed" ) );
      myQueueOfAnimals.Enqueue( new Dog( 20, "Brandy", "Beagle" ) );


      Console.WriteLine( "The stack..." );
      foreach ( Animal a in myStackOfAnimals )
      {
         Console.WriteLine(a);
      }

      Console.WriteLine( "The queue..." );
      foreach ( Animal a in myQueueOfAnimals )
      {
         Console.WriteLine( a );
      }
   }
}
Solution to Exercise 14-4.

Rewrite Exercise 14-2 to allow Animals to be sorted either by weight or alphabetically by name:

using System;
using System.Collections.Generic;

// simplified to show comparision
abstract public class Animal : IComparable<Animal>
{
   protected int weight;
   protected string name;

   public Animal( int weight, string name )
   {
      this.weight = weight;
      this.name = name;
   }

   // ** new **
   public static AnimalComparer GetComparer()
   {
      return new Animal.AnimalComparer();
   }

   public int CompareTo( Animal rhs )
   {
      return this.weight.CompareTo( rhs.weight );
   }

   // ** new **
   public int CompareTo( Animal rhs,
      Animal.AnimalComparer.ComparisonType whichComparison )
   {
      switch ( whichComparison )
      {
         case AnimalComparer.ComparisonType.name:
            return this.name.CompareTo( rhs.name );
         case AnimalComparer.ComparisonType.size:
            return this.weight.CompareTo( rhs.weight );
      }
      return -1;  // gotta have all paths return a value

   }

   // nested class   ** new **
   public class AnimalComparer : IComparer<Animal>
   {
      // how do you want to compare?
      public enum ComparisonType
      {
         Size,
         Name
      };

      private Animal.AnimalComparer.ComparisonType whichComparison;
      public Animal.AnimalComparer.ComparisonType WhichComparison
      {
         get { return whichComparison; }
         set { whichComparison = value; }
      }

      // compare two Animals using the previously set
      // whichComparison value
      public int Compare( Animal lhs, Animal rhs )
      {
         return lhs.CompareTo( rhs, whichComparison );
      }

      // required to fulfill implementation
      public bool Equals( Animal lhs, Animal rhs )
      {
         return this.Compare( lhs, rhs ) == 0;
      }

      // required to fulfill implementation
      public int GetHashCode( Animal a )
      {
         return a.weight.GetHashCode();
      }
   }     // end nested class
}        // end class Animal


public class Dog : Animal
{
   public Dog( int weight, string name, string breed ) :
   base( weight, name )
   {}

   public override string ToString()
   {
      return "My name is " + this.name + " I weigh " + this.weight;
   }
}

public class Cat : Animal
{

   public Cat( int weight, string name ) :
   base( weight, name )
   { }

   public override string ToString()
   {
      return "My name is " + this.name + " I weigh " + this.weight;
   }
}

public class Tester
{
   static void Main()
   {

      List<Animal> myAnimals = new List<Animal>();
      myAnimals.Add( new Dog( 70, "Milo", "Golden" ) );
      myAnimals.Add( new Cat( 10, "Shakespeare" ) );
      myAnimals.Add( new Cat( 15, "Allegra" ) );
      myAnimals.Add( new Dog( 50, "Dingo", "mixed breed" ) );
      myAnimals.Add( new Dog( 20, "Brandy", "Beagle" ) );

      Console.WriteLine( "Before sorting..." );
      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine( a );
      }

      Console.WriteLine( "
After sorting by default (weight)..." );
      myAnimals.Sort();
      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine( a );
      }

      Console.WriteLine( "
After sorting by name..." );
      Animal.AnimalComparer animalComparer = Animal.GetComparer();
      animalComparer.WhichComparison = Animal.AnimalComparer.ComparisonType.name;
      myAnimals.Sort( animalComparer );
      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine( a );
      }

      Console.WriteLine( "
After sorting explicitly by size..." );
      animalComparer.WhichComparison = Animal.AnimalComparer.ComparisonType.size;
      myAnimals.Sort( animalComparer );
      foreach ( Animal a in myAnimals )
      {
         Console.WriteLine( a );
      }
   }     // end main
}        // end tester
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset