オマケ 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
    }
}