I tried to implement an immutable list.
public class ImmutableList<T> : IEnumerable<T>
{
public T Head { get; set; }
public ImmutableList<T> Tail { get; set; }
protected ImmutableList()
{
}
public static ImmutableList<T> WithItems(IEnumerable<T> items)
{
if (items.Count() == 1)
{
return new ImmutableList<T>()
{
Head = items.Single(),
Tail = new EmptyList<T>()
};
}
return new ImmutableList<T>()
{
Head = items.First(),
Tail = WithItems(items.Skip(1))
};
}
public ImmutableList<T> Add(T item)
{
if (this is EmptyList<T>)
{
return new ImmutableList<T>() {Head = item, Tail = new EmptyList<T>()};
}
return new ImmutableList<T>()
{
Head = Head,
Tail = Tail.Add(item)
};
}
public IEnumerator<T> GetEnumerator()
{
if (this is EmptyList<T>) yield break;
else
{
yield return Head;
foreach (var elem in Tail)
yield return elem;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public sealed class EmptyList<T> : ImmutableList<T>
{
}
public static class ImmutableListExtensions
{
public static ImmutableList<T> ToImmutableList<T>(this IEnumerable<T> sequence)
{
return ImmutableList<T>.WithItems(sequence);
}
}
Simple example of how to use:
private static void Main(string[] args)
{
ImmutableList<int> list = new[] {1, 2, 3}.ToImmutableList();
ImmutableList<int> list2 = new EmptyList<int>().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?