Listing 1 - A minimal collection class for String types

public class List1
{
    public static String NO_ITEM = default(String);
    internal class ListNode
    {
        public ListNode next = null;
        public String obj = NO_ITEM;
    }
    internal ListNode head = null;
    internal ListNode tail = null;
    internal int length = 0;

    public List1() {}

    public virtual void Add(String obj)
    {
        if (obj == NO_ITEM)
            throw (new Exception("Cannot hold the default() value."));

        ListNode node = new ListNode();
        node.obj = obj;

        if (++length == 1)
            head = node;
        else
            tail.next = node;

        tail = node;
    }

    public virtual String Remove()
    {
        if (length > 0)
        {
            ListNode node = head;
            head = head.next;
            --length;
            return node.obj;
        }
        return NO_ITEM;
    }
}

Listing 2 - A minimal generic collection class for any type

    public class List3<T>
    {
        internal static T NO_ITEM = default(T);
        internal class ListNode
        {
            public ListNode next = null;
            public T obj = NO_ITEM;
        }
        internal ListNode head = null;
        internal ListNode tail = null;
        internal int length = 0;

        public List3() {}

        public virtual void Add(T obj)
        {
            //if (obj == NO_ITEM)
            //    throw (new Exception("Cannot hold the default() value."));

            ListNode node = new ListNode();
            node.obj = obj;

            if (++length == 1)
                head = node;
            else
                tail.next = node;

            tail = node;
        }

        public virtual T Remove()
        {
            if (length > 0)
            {
                ListNode node = head;
                head = head.next;
                --length;
                return node.obj;
            }
            return NO_ITEM;
        }
    }

Listing 3 - A class for representing bakery items

    public class BakeItem : IWatermark
    {
        private int id;

        public BakeItem(int i)
        {
            id = i;
        }

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        // Implement IWatermark
        private int highMark = default(int);
        private int lowMark = default(int);

        public int HighMark
        {
            get { return highMark; }
            set { highMark = value; }
        }

        public int LowMark
        {
            get { return lowMark; }
            set { lowMark = value; }
        }
    }

Listing 4 - A special collection to record watermarks in each item collected

    public class List4<T> : List3<T> where T : IWatermark
    {
        public override void Add(T obj)
        {
            base.Add(obj);
            obj.LowMark = length;
            for (ListNode node = head; node != null; node = node.next)
            {
                // Since T is constrained we can use the HighMark property here
                if (node.obj.HighMark < length)
                {
                    node.obj.HighMark = length;
                }
            }
        }

        public override T Remove()
        {
            T result = base.Remove();
            for (ListNode node = head; node != null; node = node.next)
            {
                // Since T is constrained we can use the LowMark property here
                if (node.obj.LowMark > length)
                {
                    node.obj.LowMark = length;
                }
            }
            return result;
        }
    }