Home   Cover Cover Cover Cover
 

Classes

/csbook/solutions/03/A10.cs
using System;

class OverflowException: Exception {}
class UnderflowException: Exception {}

// generic queue
class Queue {
  object[] values = new object[10];
  int head = 0, tail = 0;
  
  public void Enqueue(object x) {
    int tail1 = (tail + 1) % 10;
    if (tail1 == head) throw new OverflowException();
    values[tail] = x;
    tail = tail1;
  }
  
  public object Dequeue() {
    if (head == tail) throw new UnderflowException();
    object x = values[head];
    head = (head + 1) % 10;
    return x;
  }
  
  public int Length() {
    return (tail + 10 - head) % 10;
  }
}

// program that uses a queue to store integers and strings
class Test {
  
  public static void Main() {
    Queue q = new Queue();
    
    q.Enqueue(1); q.Enqueue(2); q.Enqueue(3);
    while (q.Length() > 0) {
      Console.Write((int)q.Dequeue() + " ");
    }
    Console.WriteLine();
    
    q.Enqueue("Alice"); q.Enqueue("Bob"); q.Enqueue("Charly");
    while (q.Length() > 0) {
      Console.Write((string)q.Dequeue() + " ");
    }
    Console.WriteLine();
  }
}

The difference between this "pseudo-generic" queue and a truely generic queue is that the above program can also store values of mixed types. The compiler cannot enforce a homogeneous data structure with values of the same type. If we pass an object of a value type to the queue it gets boxed. If this value is later retrieved from the queue we must cast it back to its original type. Both boxing and type casts have run-time costs.