/// <summary> /// Initializes a new instance of the <see cref="T:HeadTail`1"/> class by unwinding the given <see cref="T:IEnumerator`1"/> instance. /// </summary> /// <param name="values">The given <see cref="T:IEnumerator`1"/> instance that provides the values that should be stored /// in this <see cref="T:HeadTail`1"/> instance.</param> private HeadTail(IEnumerator <TElement> values) { this.head = values.Current; if (values.MoveNext()) { this.tail = new HeadTail <TElement> (values); } }
/// <summary> /// Enumerate all elements stored in this <see cref="T:HeadTail`1"/> instance. /// </summary> /// <returns>A <see cref="T:IEnumerable`1"/> instance containing all elements stored by this <see cref="T:HeadTail`1"/> instance.</returns> /// <remarks> /// <para>The resulting <see cref="T:IEnumerable`1"/> is guaranteed to emit at least one element: the head.</para> /// <para>The method doesn't use recursion for performance issues.</para> /// </remarks> public override IEnumerator <TElement> GetEnumerator() { IHeadTail <TElement> current = this; do { yield return(current.Head); current = current.Tail; } while(current != null); }
/// <summary> /// Initializes a new instance of the <see cref="T:HeadTail`1"/> class that contains all the elements of the given <paramref name="value"/>. /// </summary> /// <param name="values">A <see cref="T:IEnumerable`1"/> that contains the list of elements that must be stored in this <see cref="T:HeadTail`1"/> instance.</param> /// <exception cref="ArgumentNullException">If the given <paramref name="values"/> is not effective.</exception> /// <exception cref="ArgumentException">If the <see cref="T:IEnumerator`1"/> instance derived from <paramref name="values"/> is not effective.</exception> /// <exception cref="ArgumentException">If <paramref name="values"/> contains zero elements.</exception> public HeadTail(IEnumerable <TElement> values) { if (values == null) { throw new ArgumentNullException("values", "The values must be effective."); } IEnumerator <TElement> enumerator = values.GetEnumerator(); if (enumerator == null) { throw new ArgumentException("Values produced a noneffective enumerator.", "values"); } if (!enumerator.MoveNext()) { throw new ArgumentException("Values must contain at least one element.", "values"); } this.head = enumerator.Current; if (enumerator.MoveNext()) { this.tail = new HeadTail <TElement> (enumerator); } }
/// <summary> /// Determines whether the specified <see cref="object"/> is equal to the current <see cref="T:HeadTail`1"/>. /// </summary> /// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="T:HeadTail`1"/>.</param> /// <returns><c>true</c> if the specified <see cref="object"/> is equal to the current <see cref="T:HeadTail`1"/>; otherwise, <c>false</c>.</returns> /// <remarks> /// <para>The given <paramref name="obj"/> doesn't need to be a <see cref="T:HeadTail`1"/> instance, an instance /// derived from <see cref="T:IHeadTail`1"/> with the same list of objects is sufficient.</para> /// <para>The method checks at every item in the <see cref="T:IHeadTail`1"/> instances if the references are /// equal to increase performance.</para> /// </remarks> public override bool Equals(object obj) { if (object.ReferenceEquals(this, obj)) { return(true); } if (obj != null && obj is IHeadTail <TElement> ) { IHeadTail <TElement> htobj = (IHeadTail <TElement>)obj; if (!Object.Equals(this.head, htobj.Head)) { return(false); } if (this.tail != null) { return(this.tail.Equals(htobj.Tail)); } else { return(htobj.Tail == null); } } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="T:HeadTail`1"/> class with a given <paramref name="head"/> and <paramref name="tail"/>. /// </summary> /// <param name="head">The given head describing the first element of the new <see cref="T:HeadTail`1"/>.</param> /// <param name="tail">The given tail describing the rest of the elements in the new <see cref="T:HeadTail`1"/>.</param> public HeadTail(TElement head, IHeadTail <TElement> tail) { this.head = head; this.tail = tail; }