ImmutableList implementation in C# I tried to implement an immutable list. 

public class ImmutableList&lt;T&gt; : IEnumerable&lt;T&gt;
{
    public T Head { get; set; }
    public ImmutableList&lt;T&gt; Tail { get; set; }

    protected ImmutableList()
    {

    }

    public static ImmutableList&lt;T&gt; WithItems(IEnumerable&lt;T&gt; items)
    {
        if (items.Count() == 1)
        {
            return new ImmutableList&lt;T&gt;()
            {
                Head = items.Single(),
                Tail = new EmptyList&lt;T&gt;()
            };
        }

        return new ImmutableList&lt;T&gt;()
        {
            Head = items.First(),
            Tail = WithItems(items.Skip(1))
        };
    }

    public ImmutableList&lt;T&gt; Add(T item)
    {
        if (this is EmptyList&lt;T&gt;)
        {
            return new ImmutableList&lt;T&gt;() {Head = item, Tail = new EmptyList&lt;T&gt;()};
        }

        return new ImmutableList&lt;T&gt;()
        {
            Head = Head,
            Tail = Tail.Add(item)
        };
    }

    public IEnumerator&lt;T&gt; GetEnumerator()
    {
        if (this is EmptyList&lt;T&gt;) yield break;
        else
        {
            yield return Head;
            foreach (var elem in Tail)
                yield return elem;
        }
    }

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

public sealed class EmptyList&lt;T&gt; : ImmutableList&lt;T&gt;
{

}

public static class ImmutableListExtensions
{
    public static ImmutableList&lt;T&gt; ToImmutableList&lt;T&gt;(this IEnumerable&lt;T&gt; sequence)
    {
        return ImmutableList&lt;T&gt;.WithItems(sequence);
    } 
}


Simple example of how to use:

private static void Main(string[] args)
{
    ImmutableList&lt;int&gt; list = new[] {1, 2, 3}.ToImmutableList();


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

    foreach (var n in list)
    {
        Console.WriteLine(n);
    }
}


Is there a better and/or more efficient way to do this?
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.