Our stacks and queues don’t exist in isolation - they have to interoperate with standard framework classes and other domain constructs to be useful. For example, it is extremely useful to have some factory methods to make it easier to construct stacks and queues from existing lists and sequences.

To begin, let’s implement a couple of extension methods - .EnqueueAll() to add everything from a sequence onto a queue, and .ToQueue to convert a sequence directly into a queue.

public static class ImmutableQueueExtensions
    public static IImmutableQueue<T> EnqueueAll<T>(
        this IImmutableQueue<T> queue, IEnumerable<T> items)
        => items.Aggregate(
            (q, i) => q.Enqueue(i));

    public static IImmutableQueue<T> ToQueue<T>(
        this IEnumerable<T> items)
        where T : IEquatable<T>
        => ImmutableQueue<T>.Empty.EnqueueAll(items);

With that support, we can now write a static class with methods for making new Immutable Queues:

public static class ImmutableQueue<T>
    where T : IEquatable<T>
    // Create a new, empty queue
    public static IImmutableQueue<T> Empty { get; }
        = new EmptyImmutableQueue<T>();

    // Create a queue containing specified items
    public static IImmutableQueue<T> Create(IEnumerable<T> items)
        => ImmutableQueue<T>.Empty.EnqueueAll(items);

    // Create a queue containing specified items
    public static IImmutableQueue<T> Create(params T[] items)
        => ImmutableQueue<T>.Empty.EnqueueAll(items);

    // Create a queue containing a single item
    public static IImmutableQueue<T> Create(T item)
        => ImmutableQueue<T>.Empty.Enqueue(item);

You’ll observe that we now have two ways to create a new queue from an existing sequence - by calling the static method ImmutableQueue.Create() and by using the extension method .ToQueue(). Depending on your context and preferences, you might prefer to drop one or the other.

There are similar methods that you can - and should - write for stacks, but I’ll leave those as an exercise for the reader. They’re very much the same as the ones shown here for queues, but with the wrinkle that items on a stack come off in the reverse order, so you’ll need to think through the semantics carefully before you start.

Prior post in this series:
Queue Concatenation
Next post in this series:
Testing Immutable Types


blog comments powered by Disqus