1 public class Chain<T> : IEnumerable<T>, IEnumerable
2 {
3 private static readonly Chain<T> empty = new Chain<T>(default(T), null);
4 public static Chain<T> Empty
5 {
6 get { return empty; }
7 }
8
9 public static Chain<T> From(T t)
10 {
11 return Empty.Append(t);
12 }
13
14 public static Chain<T> From(IEnumerable<T> _Items)
15 {
16 return Empty.Append(_Items);
17 }
18
19 public static Chain<T> From(params T[] items)
20 {
21 return Empty.Append(items);
22 }
23
24 private readonly T item;
25 private readonly Chain<T> next;
26
27 private IEnumerable<T> GetItemsRecursive()
28 {
29 if (next != null) {
30 foreach (T child in next.GetItemsRecursive()) yield return child;
31 yield return item;
32 }
33 }
34
35 public Chain<T> Append(T t)
36 {
37 return new Chain<T>(t, this);
38 }
39
40 public Chain<T> Append(IEnumerable<T> _Items)
41 {
42 if (_Items == null) throw new ArgumentNullException("Items");
43 Chain<T> current = this;
44 foreach (T cur in _Items) {
45 current = current.Append(cur);
46 }
47 return current;
48 }
49
50 public Chain<T> Append(params T[] items)
51 {
52 return Append((IEnumerable<T>) items);
53 }
54
55 private Chain(T _Item, Chain<T> _Next)
56 {
57 item = _Item;
58 next = _Next;
59 }
60
61 public IEnumerator<T> GetEnumerator()
62 {
63 return GetItemsRecursive().GetEnumerator();
64 }
65
66 IEnumerator IEnumerable.GetEnumerator()
67 {
68 return GetItemsRecursive().GetEnumerator();
69 }
70 }