0

I'm trying to implement generic Queue based on Array as data structure.

public class ArrayQueue<T>
{
        public T Dequeue()
        {
            if (Queue[Tail] == null)
                return null;

            T value = Queue[Tail];
            Queue[Tail] = null;
            Tail--;
            if (Tail - Head < Queue.Length / (ResizeCoefficient * 2))
                ResizeQueue(Queue.Length / ResizeCoefficient);
            return value;
        }
...
private T[] Queue;
}

As you can see, I'm using null as "empty" cell and not default(T). That's because if T is int, default(int) = 0 and 0 can be valid input, not empty value. So T must be reference type or Nullable. But i don't want client to bother about it, class should support both ArrayQueue<int> and ArrayQueue<Product>.

Can you suggest any solution with generic class without constrains and in the same time being able to have Array of type that can be null?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 1
    For value types how about using Nullable instead of T then you can distinguish between unset and set to default. – James Lucas May 01 '15 at 06:35
  • 1
    You could use an `object[]` array instead of a `T[]` as your store. Then cast/unbox to get your value back. Horrible, I know. – Wai Ha Lee May 01 '15 at 06:36
  • 1
    @JamesLucas: You mean instead of `ArrayQueue`, use `ArrayQueue>`? – John Saunders May 01 '15 at 06:36
  • 1
    What you're asking for is impossible. Your `Dequeue` method returns a `T` instance so if `T` is `int` then it's not possible to return `null`. Either `T` must be a nullable value type or `Dequeue` must return type `Nullable`. You can't have it both ways. – jmcilhinney May 01 '15 at 06:39
  • yes then everything in the queue becomes a reference type – James Lucas May 01 '15 at 06:39
  • In that case i have to define array of some type that can contain both nullable and reference - object[] = IsNullable? T[] : Nullable. I'll try, thx! – Konstantin Brodin May 01 '15 at 06:39
  • 8
    Why does it matter if `default(T)` is a valid value? You should be able to keep track of where your queue's head and tail are without using `null` as some kind of flag. Don't forget that `null` is usually a "valid" value for reference types in collections too. – Rawling May 01 '15 at 06:40
  • Rawling, you're absolutely right, thanks! – Konstantin Brodin May 01 '15 at 06:43

1 Answers1

2

The value null should also be a valid value inside your queue. It should not be used to keep track of your tail.

Try to implement a counter or an index which can tell you how many elements are in the queue or where the tail ends. Using this you can insert and return ANY value, including null, 0, default(T), etc.

Maybe a good idea to look at the code of the System.Collections.Generic.Queue.

Martin Mulder
  • 12,642
  • 3
  • 25
  • 54