Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / Enumerable.cs / 1407647 / Enumerable.cs
using System; using System.Collections; using System.Collections.Generic; using System.Threading; // Include Silverlight's managed resources #if SILVERLIGHT using System.Core; #endif //SILVERLIGHT namespace System.Linq { public static class Enumerable { public static IEnumerableWhere (this IEnumerable source, Func predicate) { if (source == null) throw Error.ArgumentNull("source"); if (predicate == null) throw Error.ArgumentNull("predicate"); if (source is Iterator ) return ((Iterator )source).Where(predicate); if (source is TSource[]) return new WhereArrayIterator ((TSource[])source, predicate); if (source is List ) return new WhereListIterator ((List )source, predicate); return new WhereEnumerableIterator (source, predicate); } public static IEnumerable Where (this IEnumerable source, Func predicate) { if (source == null) throw Error.ArgumentNull("source"); if (predicate == null) throw Error.ArgumentNull("predicate"); return WhereIterator (source, predicate); } static IEnumerable WhereIterator (IEnumerable source, Func predicate) { int index = -1; foreach (TSource element in source) { checked { index++; } if (predicate(element, index)) yield return element; } } public static IEnumerable Select (this IEnumerable source, Func selector) { if (source == null) throw Error.ArgumentNull("source"); if (selector == null) throw Error.ArgumentNull("selector"); if (source is Iterator ) return ((Iterator )source).Select(selector); if (source is TSource[]) return new WhereSelectArrayIterator ((TSource[])source, null, selector); if (source is List ) return new WhereSelectListIterator ((List )source, null, selector); return new WhereSelectEnumerableIterator (source, null, selector); } public static IEnumerable Select (this IEnumerable source, Func selector) { if (source == null) throw Error.ArgumentNull("source"); if (selector == null) throw Error.ArgumentNull("selector"); return SelectIterator (source, selector); } static IEnumerable SelectIterator (IEnumerable source, Func selector) { int index = -1; foreach (TSource element in source) { checked { index++; } yield return selector(element, index); } } static Func CombinePredicates (Func predicate1, Func predicate2) { return x => predicate1(x) && predicate2(x); } static Func CombineSelectors (Func selector1, Func selector2) { return x => selector2(selector1(x)); } abstract class Iterator : IEnumerable , IEnumerator { int threadId; internal int state; internal TSource current; public Iterator() { threadId = Thread.CurrentThread.ManagedThreadId; } public TSource Current { get { return current; } } public abstract Iterator Clone(); public virtual void Dispose() { current = default(TSource); state = -1; } public IEnumerator GetEnumerator() { if (threadId == Thread.CurrentThread.ManagedThreadId && state == 0) { state = 1; return this; } Iterator duplicate = Clone(); duplicate.state = 1; return duplicate; } public abstract bool MoveNext(); public abstract IEnumerable Select (Func selector); public abstract IEnumerable Where(Func predicate); object IEnumerator.Current { get { return Current; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } void IEnumerator.Reset() { throw new NotImplementedException(); } } class WhereEnumerableIterator : Iterator { IEnumerable source; Func predicate; IEnumerator enumerator; public WhereEnumerableIterator(IEnumerable source, Func predicate) { this.source = source; this.predicate = predicate; } public override Iterator Clone() { return new WhereEnumerableIterator (source, predicate); } public override void Dispose() { if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose(); enumerator = null; base.Dispose(); } public override bool MoveNext() { switch (state) { case 1: enumerator = source.GetEnumerator(); state = 2; goto case 2; case 2: while (enumerator.MoveNext()) { TSource item = enumerator.Current; if (predicate(item)) { current = item; return true; } } Dispose(); break; } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectEnumerableIterator (source, predicate, selector); } public override IEnumerable Where(Func predicate) { return new WhereEnumerableIterator (source, CombinePredicates(this.predicate, predicate)); } } class WhereArrayIterator : Iterator { TSource[] source; Func predicate; int index; public WhereArrayIterator(TSource[] source, Func predicate) { this.source = source; this.predicate = predicate; } public override Iterator Clone() { return new WhereArrayIterator (source, predicate); } public override bool MoveNext() { if (state == 1) { while (index < source.Length) { TSource item = source[index]; index++; if (predicate(item)) { current = item; return true; } } Dispose(); } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectArrayIterator (source, predicate, selector); } public override IEnumerable Where(Func predicate) { return new WhereArrayIterator (source, CombinePredicates(this.predicate, predicate)); } } class WhereListIterator : Iterator { List source; Func predicate; List .Enumerator enumerator; public WhereListIterator(List source, Func predicate) { this.source = source; this.predicate = predicate; } public override Iterator Clone() { return new WhereListIterator (source, predicate); } public override bool MoveNext() { switch (state) { case 1: enumerator = source.GetEnumerator(); state = 2; goto case 2; case 2: while (enumerator.MoveNext()) { TSource item = enumerator.Current; if (predicate(item)) { current = item; return true; } } Dispose(); break; } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectListIterator (source, predicate, selector); } public override IEnumerable Where(Func predicate) { return new WhereListIterator (source, CombinePredicates(this.predicate, predicate)); } } class WhereSelectEnumerableIterator : Iterator { IEnumerable source; Func predicate; Func selector; IEnumerator enumerator; public WhereSelectEnumerableIterator(IEnumerable source, Func predicate, Func selector) { this.source = source; this.predicate = predicate; this.selector = selector; } public override Iterator Clone() { return new WhereSelectEnumerableIterator (source, predicate, selector); } public override void Dispose() { if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose(); enumerator = null; base.Dispose(); } public override bool MoveNext() { switch (state) { case 1: enumerator = source.GetEnumerator(); state = 2; goto case 2; case 2: while (enumerator.MoveNext()) { TSource item = enumerator.Current; if (predicate == null || predicate(item)) { current = selector(item); return true; } } Dispose(); break; } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectEnumerableIterator (source, predicate, CombineSelectors(this.selector, selector)); } public override IEnumerable Where(Func predicate) { return new WhereEnumerableIterator (this, predicate); } } class WhereSelectArrayIterator : Iterator { TSource[] source; Func predicate; Func selector; int index; public WhereSelectArrayIterator(TSource[] source, Func predicate, Func selector) { this.source = source; this.predicate = predicate; this.selector = selector; } public override Iterator Clone() { return new WhereSelectArrayIterator (source, predicate, selector); } public override bool MoveNext() { if (state == 1) { while (index < source.Length) { TSource item = source[index]; index++; if (predicate == null || predicate(item)) { current = selector(item); return true; } } Dispose(); } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectArrayIterator (source, predicate, CombineSelectors(this.selector, selector)); } public override IEnumerable Where(Func predicate) { return new WhereEnumerableIterator (this, predicate); } } class WhereSelectListIterator : Iterator { List source; Func predicate; Func selector; List .Enumerator enumerator; public WhereSelectListIterator(List source, Func predicate, Func selector) { this.source = source; this.predicate = predicate; this.selector = selector; } public override Iterator Clone() { return new WhereSelectListIterator (source, predicate, selector); } public override bool MoveNext() { switch (state) { case 1: enumerator = source.GetEnumerator(); state = 2; goto case 2; case 2: while (enumerator.MoveNext()) { TSource item = enumerator.Current; if (predicate == null || predicate(item)) { current = selector(item); return true; } } Dispose(); break; } return false; } public override IEnumerable Select (Func selector) { return new WhereSelectListIterator (source, predicate, CombineSelectors(this.selector, selector)); } public override IEnumerable Where(Func predicate) { return new WhereEnumerableIterator (this, predicate); } } //public static IEnumerable Where (this IEnumerable source, Func predicate) { // if (source == null) throw Error.ArgumentNull("source"); // if (predicate == null) throw Error.ArgumentNull("predicate"); // return WhereIterator (source, predicate); //} //static IEnumerable WhereIterator (IEnumerable source, Func predicate) { // foreach (TSource element in source) { // if (predicate(element)) yield return element; // } //} //public static IEnumerable Select (this IEnumerable source, Func selector) { // if (source == null) throw Error.ArgumentNull("source"); // if (selector == null) throw Error.ArgumentNull("selector"); // return SelectIterator (source, selector); //} //static IEnumerable SelectIterator (IEnumerable source, Func selector) { // foreach (TSource element in source) { // yield return selector(element); // } //} public static IEnumerable SelectMany (this IEnumerable source, Func > selector) { if (source == null) throw Error.ArgumentNull("source"); if (selector == null) throw Error.ArgumentNull("selector"); return SelectManyIterator (source, selector); } static IEnumerable SelectManyIterator (IEnumerable source, Func > selector) { foreach (TSource element in source) { foreach (TResult subElement in selector(element)) { yield return subElement; } } } public static IEnumerable SelectMany (this IEnumerable source, Func > selector) { if (source == null) throw Error.ArgumentNull("source"); if (selector == null) throw Error.ArgumentNull("selector"); return SelectManyIterator (source, selector); } static IEnumerable SelectManyIterator (IEnumerable source, Func > selector) { int index = -1; foreach (TSource element in source) { checked { index++; } foreach (TResult subElement in selector(element, index)) { yield return subElement; } } } public static IEnumerable SelectMany (this IEnumerable source, Func > collectionSelector, Func resultSelector) { if (source == null) throw Error.ArgumentNull("source"); if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector"); if (resultSelector == null) throw Error.ArgumentNull("resultSelector"); return SelectManyIterator (source, collectionSelector, resultSelector); } static IEnumerable SelectManyIterator (IEnumerable source, Func > collectionSelector, Func resultSelector){ int index = -1; foreach (TSource element in source){ checked { index++; } foreach (TCollection subElement in collectionSelector(element, index)){ yield return resultSelector(element, subElement); } } } public static IEnumerable SelectMany (this IEnumerable source, Func > collectionSelector, Func resultSelector) { if (source == null) throw Error.ArgumentNull("source"); if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector"); if (resultSelector == null) throw Error.ArgumentNull("resultSelector"); return SelectManyIterator (source, collectionSelector, resultSelector); } static IEnumerable SelectManyIterator (IEnumerable source, Func > collectionSelector, Func resultSelector) { foreach (TSource element in source) { foreach (TCollection subElement in collectionSelector(element)) { yield return resultSelector(element, subElement); } } } public static IEnumerable Take (this IEnumerable source, int count) { if (source == null) throw Error.ArgumentNull("source"); return TakeIterator (source, count); } static IEnumerable TakeIterator (IEnumerable source, int count) { if (count > 0) { foreach (TSource element in source) { yield return element; if (--count == 0) break; } } } public static IEnumerable TakeWhile (this IEnumerable source, Func predicate) { if (source == null) throw Error.ArgumentNull("source"); if (predicate == null) throw Error.ArgumentNull("predicate"); return TakeWhileIterator (source, predicate); } static IEnumerable TakeWhileIterator (IEnumerable source, Func predicate) { foreach (TSource element in source) { if (!predicate(element)) break; yield return element; } } public static IEnumerable TakeWhile (this IEnumerable source, Func predicate) { if (source == null) throw Error.ArgumentNull("source"); if (predicate == null) throw Error.ArgumentNull("predicate"); return TakeWhileIterator (source, predicate); } static IEnumerable TakeWhileIterator (IEnumerable source, Func predicate) { int index = -1; foreach (TSource element in source) { checked { index++; } if (!predicate(element, index)) break; yield return element; } } public static IEnumerable Skip (this IEnumerable source, int count) { if (source == null) throw Error.ArgumentNull("source"); return SkipIterator (source, count); } static IEnumerable SkipIterator (IEnumerable source, int count) { using (IEnumerator e = source.GetEnumerator()) { while (count > 0 && e.MoveNext()) count--; if (count <= 0) { while (e.MoveNext()) yield return e.Current; } } } public static IEnumerable SkipWhile (this IEnumerable source, Func