ImmutableList implementation in C#
First of all, this class is not immutable at all. You can modify both the head and the tail at any given node in the list from calling code. Here are some quick fixes to make the list immutable:

public class ImmutableList&lt;T&gt; : IEnumerable&lt;T&gt;
{
    private static readonly ImmutableList&lt;T&gt; _Empty = new EmptyList&lt;T&gt;();

    private readonly T _Head;

    private readonly ImmutableList&lt;T&gt; _Tail;

    public static ImmutableList&lt;T&gt; Empty
    {
        get
        {
            return _Empty;
        }
    }

    public T Head
    {
        get
        {
            return this._Head;
        }
    }

    public ImmutableList&lt;T&gt; Tail
    {
        get
        {
            return this._Tail;
        }
    }

    protected ImmutableList(T head, ImmutableList&lt;T&gt; tail)
    {
        this._Head = head;
        this._Tail = tail;
    }

    public static ImmutableList&lt;T&gt; WithItems(IEnumerable&lt;T&gt; items)
    {
        return (items == null) || (!items.Any())
            ? _Empty
            : (items.Count() == 1
                ? new ImmutableList&lt;T&gt;(items.Single(), _Empty)
                : new ImmutableList&lt;T&gt;(items.First(), WithItems(items.Skip(1))));
    }

    public ImmutableList&lt;T&gt; Add(T item)
    {
        return this == _Empty
            ? new ImmutableList&lt;T&gt;(item, _Empty)
            : new ImmutableList&lt;T&gt;(this._Head, this._Tail.Add(item));
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        if (this == _Empty)
        {
            yield break;
        }

        yield return this._Head;
        foreach (var elem in this._Tail)
        {
            yield return elem;
        }
    }

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

    private sealed class EmptyList&lt;TU&gt; : ImmutableList&lt;TU&gt;
    {
        public EmptyList() : base(default(TU), null)
        {
        }
    }
}


The calling code needs to change ever so slightly to accommodate:

var list2 = ImmutableList&lt;int&gt;.Empty.Add(1).Add(2).Add(3).Add(4);


You'll also note I added a null and empty sequence check in the WithItems static method. This simply allows any null/empty sequence call to return an empty list.