Care to review my immutable singly linked list? public sealed class SinglyLinkedList&lt;T&gt; : IEnumerable&lt;T&gt;
{
    readonly static SinglyLinkedList&lt;T&gt; _empty = new SinglyLinkedList&lt;T&gt;();
    readonly bool _isEmpty;
    readonly T _head;
    readonly SinglyLinkedList&lt;T&gt; _tail;

    private SinglyLinkedList()
    {
        _isEmpty = true;
    }

    private SinglyLinkedList(T head)
    {
        _isEmpty = false;
        _head = head;
    }

    private SinglyLinkedList(T head, SinglyLinkedList&lt;T&gt; tail)
    {
        _isEmpty = false;
        _head = head;
        _tail = tail;
    }

    public static SinglyLinkedList&lt;T&gt; Empty
    {
        get { return _empty; }
    }

    public int Count
    {
        get 
        {
            var list = this;
            var count = 0;
            while (!list._isEmpty)
            {
                count++;
                list = list._tail;
            }
            return count; 
        }
    }

    public bool IsEmpty
    {
        get { return _isEmpty; }
    }

    public T Head
    {
        get
        {
            if (_isEmpty)
                throw new InvalidOperationException("The list is empty.");
            return _head;
        }
    }

    public SinglyLinkedList&lt;T&gt; Tail
    {
        get
        {
            if (_tail == null)
                throw new InvalidOperationException("This list has no tail.");
            return _tail;
        }
    }

    public static SinglyLinkedList&lt;T&gt; FromEnumerable(IEnumerable&lt;T&gt; e)
    {
        if (e == null)
            throw new ArgumentNullException("e");
        return FromArrayInternal(e.ToArray());
    }

    public static SinglyLinkedList&lt;T&gt; FromArray(params T[] a)
    {
        if (a == null)
            throw new ArgumentNullException("a");
        return FromArrayInternal(a);
    }

    public SinglyLinkedList&lt;T&gt; Append(T value)
    {
        var array = new T[Count + 1]; 
        var list = this;
        var index = 0;
        while (!list._isEmpty)
        {
            array[index++] = list._head;
            list = list._tail;
        }
        array[index] = value;
        return FromArrayInternal(array);
    }

    public SinglyLinkedList&lt;T&gt; Prepend(T value)
    {
        return new SinglyLinkedList&lt;T&gt;(value, this);
    }       

    public SinglyLinkedList&lt;T&gt; Insert(int index, T value)
    {
        if (index &lt; 0)
            throw new ArgumentOutOfRangeException("index", "Cannot be less than zero.");
        var count = Count;
        if (index &gt;= count)
            throw new ArgumentOutOfRangeException("index", "Cannot be greater than count.");
        var array = new T[Count + 1]; 
        var list = this;
        var arrayIndex = 0;
        while (!list._isEmpty)
        {
            if (arrayIndex == index)
            {
                array[arrayIndex++] = value;
            }
            array[arrayIndex++] = list._head;
            list = list._tail;
        }
        return FromArrayInternal(array);
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        var list = this;
        while (!list._isEmpty)
        {
            yield return list._head;
            list = list._tail;
        }
    }

    public override string ToString()
    {
        if (_isEmpty)
            return "[]";
        return string.Format("[{0}...]", _head);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    static SinglyLinkedList&lt;T&gt; FromArrayInternal(T[] a)
    {
        var result = Empty;
        for (var i = a.Length - 1; i &gt;= 0; i--)
        {
            result = result.Prepend(a[i]);
        }
        return result;
    }
}
The constructor with one argument is never used and doesn't make much sense (list with a head but no tail?).
You shouldn't use Count in your own methods unless absolutely necessary, because it's O(n). Or you should cache the result in a field.
Because you use Count so often, your Insert() walks through the whole list three times! The second time it's because of completely unnecessary Count. You should completely rewrite it, Insert() can be done in O(index), which can be much better than your O(n).