オマケ LinkList.cs
オマケなので機能的には問題があると思われる。Insert() とか(笑
// code coloring/formated by http://manoli.net/csharpformat/ using System; using System.Collections; using System.Collections.Generic; namespace Lx.Collections.Generic { /// <summary>単方向リンクリスト データ構造。</summary> public class LinkList<T> : IList<T> { private T value = default(T); private LinkList<T> next = null; /// <summary>新しいリストを作成する。<summary> public LinkList() {} /// <summary>新しいリストを作成する<summary> /// <param name="value">格納する初期値</param> public LinkList(T value) : this() { this.value = value; } /// <summary>現在のノードが保持している値</summary> public T Value { get { return this.value; } set { this.value = value; } } /// <summary>次のノード、または終端をあらわす null。</summary> public LinkList<T> Next { get { return this.next; } } /// <summary>終端ノード</summary> public LinkList<T> Last { get { return (this.Next == null) ? this : this.Next.Last; } } internal void SetNext(LinkList<T> next) { this.next = next; } /// <summary>このノードの後ろへ新しい値を挿入する。</summary> public LinkList<T> Insert(T value) { LinkList<T> node = new LinkList<T>(value); node.next = this.next; this.next = node; return node; } /// <summary>このリストの末尾へ新しい値を追加する。</summary> public LinkList<T> Append(T item) { LinkList<T> cur = this; while (cur.Next != null) cur = cur.Next; return cur.Insert(item); } /// <summary>このノードから後ろへノードを列挙する。</summary> public IEnumerable<LinkList<T>> Walk() { for (LinkList<T> cur = this; cur != null; cur = cur.Next) { yield return cur; } } #region IList<T> メンバ private LinkList<T> GetNodeBy(int index) { if (index < 0) throw new ArgumentOutOfRangeException("index"); IEnumerator<LinkList<T>> e = this.Walk().GetEnumerator(); while (e.MoveNext()) { if (index-- == 0) return e.Current; } throw new ArgumentOutOfRangeException("index"); } T IList<T>.this[int index] { get { return GetNodeBy(index).Value; } set { GetNodeBy(index).Value = value; } } int IList<T>.IndexOf(T item) { int index = 0; foreach (T value in this) { if (object.Equals(item, value)) return index; index++; } return -1; } void IList<T>.Insert(int index, T item) { if (index == 0) { throw new ArgumentException("index"); } else if (index == 1) { this.Insert(item); } else { this.GetNodeBy(index - 1).Insert(item); } } void IList<T>.RemoveAt(int index) { if (index < 0) throw new ArgumentOutOfRangeException("index"); if (index == 0) throw new ArgumentException("index"); LinkList<T> prev = this.GetNodeBy(index - 1); if (prev.next != null) { prev.next = prev.next.next; } else { throw new ArgumentOutOfRangeException("index"); } } #region ICollection<T> メンバ /// <suymmary><see>ICollection<T>.Count</see></summary> public int Count { get { int c = 0; foreach (T value in this) c++; return c; } } bool ICollection<T>.IsReadOnly { get { return false; } } void ICollection<T>.Add(T item) { this.Append(item); } void ICollection<T>.Clear() { throw new NotSupportedException(); } /// <suymmary><see>ICollection<T>.Contains(T)</see></summary> public bool Contains(T item) { foreach (T value in this) { if (object.Equals(item, value)) return true; } return false; } /// <suymmary><see>ICollection<T>.CopyTo(T,int)</see></summary> public void CopyTo(T[] array, int index) { foreach (T value in this) array[index++] = value; } /// <suymmary><see>ICollection<T>.Remove(T)</see></summary> public bool Remove(T item) { LinkList<T> cur = this; while (cur.Next != null) { if (object.Equals(item, cur.Next.Value)) { cur.next = cur.Next.next; return true; } } return false; } #region IEnumerable<T> メンバ /// <summary><see>IEnumerable<T>.GetEnumerator()</see></summary> public IEnumerator<T> GetEnumerator() { foreach (LinkList<T> cur in this.Walk()) { yield return cur.Value; } } #region IEnumerable メンバ IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } #endregion #endregion #endregion #endregion } }