// Needed for NET40 #if !NET_4_6 using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using LinqInternal.Collections.Specialized; using LinqInternal.Collections.ThreadSafe; using LinqInternal.Core; namespace LinqInternal.Collections { [System.Diagnostics.DebuggerNonUserCode] internal static partial class Extensions { public static void Add(this Stack stack, T item) { if (stack == null) { throw new ArgumentNullException("stack"); } stack.Push(item); } public static void Add(this Queue queue, T item) { if (queue == null) { throw new ArgumentNullException("queue"); } queue.Enqueue(item); } public static T[] AddFirst(this IList list, T item) { if (list == null) { throw new ArgumentNullException("list"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var res = new T[list.Count + 1]; res[0] = item; list.CopyTo(res, 1); return res; } public static void CanCopyTo(int count, Array array) { if (array == null) { throw new ArgumentNullException("array"); } if (count > array.Length) { throw new ArgumentException("The array can not contain the number of elements.", "array"); } } public static void CanCopyTo(int count, Array array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required."); } if (count > array.Length - arrayIndex) { throw new ArgumentException("The array can not contain the number of elements.", "array"); } } public static void CanCopyTo(int count, T[] array) { if (array == null) { throw new ArgumentNullException("array"); } if (count > array.Length) { throw new ArgumentException("The array can not contain the number of elements.", "array"); } } public static void CanCopyTo(int count, T[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required."); } if (count > array.Length - arrayIndex) { throw new ArgumentException("The array can not contain the number of elements.", "array"); } } public static void CanCopyTo(T[] array, int arrayIndex, int countLimit) { if (array == null) { throw new ArgumentNullException("array"); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required."); } if (countLimit < 0) { throw new ArgumentOutOfRangeException("countLimit", "Non-negative number is required."); } if (countLimit > array.Length - arrayIndex) { throw new ArgumentException("The array can not contain the number of elements.", "array"); } } public static IEnumerable Clone(this IEnumerable target) { return new List(target); } public static void Consume(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } foreach (var element in source) { GC.KeepAlive(element); } } public static bool ContainsAny(this IEnumerable source, IEnumerable items) { if (source == null) { throw new ArgumentNullException("source"); } if (items == null) { throw new ArgumentNullException("items"); } IEqualityComparer comparer = EqualityComparer.Default; var localCollection = AsCollection(source); foreach (var item in items) { if (localCollection.Contains(item, comparer)) { return true; } } return false; } public static bool ContainsAny(this IEnumerable source, IEnumerable items, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (items == null) { throw new ArgumentNullException("items"); } comparer = comparer ?? EqualityComparer.Default; var localCollection = AsCollection(source); foreach (var item in items) { if (localCollection.Contains(item, comparer)) { return true; } } return false; } public static List ConvertAll(this IEnumerable source, Func converter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } var result = new List(); foreach (var item in source) { result.Add(converter(item)); } return result; } public static TList ConvertAll(this IEnumerable source, Func converter) where TList : ICollection, new() { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } var result = new TList(); foreach (var item in source) { result.Add(converter(item)); } return result; } public static List ConvertFiltered(this IEnumerable source, Func converter, Predicate filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var result = new List(); foreach (var item in source) { if (filter(item)) { result.Add(converter(item)); } } return result; } public static List ConvertFiltered(this IEnumerable source, Func converter, Func filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new List(); foreach (var item in source) { if (filter(item, index)) { result.Add(converter(item)); } index++; } return result; } public static TList ConvertFiltered(this IEnumerable source, Func converter, Predicate filter) where TList : ICollection, new() { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var result = new TList(); foreach (var item in source) { if (filter(item)) { result.Add(converter(item)); } } return result; } public static TList ConvertFiltered(this IEnumerable source, Func converter, Func filter) where TList : ICollection, new() { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new TList(); foreach (var item in source) { if (filter(item, index)) { result.Add(converter(item)); } index++; } return result; } public static List> ConvertIndexed(this IEnumerable source, Func converter, Predicate filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new List>(); foreach (var item in source) { if (filter(item)) { result.Add(new KeyValuePair(index, converter(item))); } index++; } return result; } public static List> ConvertIndexed(this IEnumerable source, Func converter, Func filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new List>(); foreach (var item in source) { if (filter(item, index)) { result.Add(new KeyValuePair(index, converter(item))); } index++; } return result; } public static TList ConvertIndexed(this IEnumerable source, Func converter, Predicate filter) where TList : ICollection>, new() { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new TList(); foreach (var item in source) { if (filter(item)) { result.Add(new KeyValuePair(index, converter(item))); } index++; } return result; } public static TList ConvertIndexed(this IEnumerable source, Func converter, Func filter) where TList : ICollection>, new() { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; var result = new TList(); foreach (var item in source) { if (filter(item, index)) { result.Add(new KeyValuePair(index, converter(item))); } index++; } return result; } public static IEnumerable ConvertProgressive(this IEnumerable source, Func converter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } foreach (var item in source) { yield return converter(item); } } public static IEnumerable ConvertProgressiveFiltered(this IEnumerable source, Func converter, Predicate filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } foreach (var item in source) { if (filter(item)) { yield return converter(item); } } } public static IEnumerable ConvertProgressiveFiltered(this IEnumerable source, Func converter, Func filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; foreach (var item in source) { if (filter(item, index)) { yield return converter(item); } index++; } } public static IEnumerable> ConvertProgressiveIndexed(this IEnumerable source, Func converter, Predicate filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; foreach (var item in source) { if (filter(item)) { yield return new KeyValuePair(index, converter(item)); } index++; } } public static IEnumerable> ConvertProgressiveIndexed(this IEnumerable source, Func converter, Func filter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } if (filter == null) { throw new ArgumentNullException("filter"); } var index = 0; foreach (var item in source) { if (filter(item, index)) { yield return new KeyValuePair(index, converter(item)); } index++; } } public static T[] Copy(this T[] array) { if (array == null) { throw new ArgumentNullException("array"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var copy = new T[array.Length]; Array.Copy(array, copy, array.Length); return copy; } public static void CopyTo(this IEnumerable source, T[] array) { CopyTo(source, array, 0); } public static void CopyTo(this IEnumerable source, T[] array, int arrayIndex) { if (source == null) { throw new ArgumentNullException("source"); } if (array == null) { throw new ArgumentNullException("array"); } try { var index = arrayIndex; foreach (var item in source) { array[index] = item; index++; } } catch (IndexOutOfRangeException exception) { throw new ArgumentException(exception.Message, "array"); } } public static void CopyTo(this IEnumerable source, T[] array, int arrayIndex, int countLimit) { CopyTo(source.TakeItems(countLimit), array, arrayIndex); } public static int CountContiguousItems(this IEnumerable source, T item) { if (source == null) { throw new ArgumentNullException("source"); } var result = 0; var equalityComparer = EqualityComparer.Default; foreach (var value in source) { if (equalityComparer.Equals(value, item)) { result++; } else { break; } } return result; } public static int CountContiguousItemsWhere(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var result = 0; foreach (var item in source) { if (predicate(item)) { result++; } else { break; } } return result; } public static int CountItems(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } var result = 0; foreach (var value in source) { result++; GC.KeepAlive(value); } return result; } public static int CountItems(this IEnumerable source, T item) { if (source == null) { throw new ArgumentNullException("source"); } var result = 0; var equalityComparer = EqualityComparer.Default; foreach (var value in source) { if (equalityComparer.Equals(value, item)) { result++; } } return result; } public static int CountItemsWhere(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var result = 0; foreach (var item in source) { if (predicate(item)) { result++; } } return result; } public static void DeprecatedCopyTo(this IEnumerable source, Array array) { if (source == null) { throw new ArgumentNullException("source"); } if (array == null) { throw new ArgumentNullException("array"); } var index = 0; foreach (var item in source) { array.SetValue(item, index++); } } public static void DeprecatedCopyTo(this IEnumerable source, Array array, int index) { if (source == null) { throw new ArgumentNullException("source"); } if (array == null) { throw new ArgumentNullException("array"); } foreach (var item in source) { array.SetValue(item, index++); } } public static IEnumerable EmptyChecked(this IEnumerable source, Action onEmpty) { if (source == null) { throw new ArgumentNullException("source"); } if (onEmpty == null) { throw new ArgumentException("onEmpty"); } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } } return NullOrEmptyCheckedExtracted(source, onEmpty); } public static IEnumerable EmptyChecked(this IEnumerable source, Action onEmpty, Action onNotEmpty) { if (source == null) { throw new ArgumentNullException("source"); } if (onEmpty == null) { throw new ArgumentException("onEmpty"); } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } onNotEmpty(); } return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty); } public static IEnumerable EmptyChecked(this IEnumerable source, Action onEmpty, Action onUnknownSize, Action onKnownSize) { if (source == null) { throw new ArgumentNullException("source"); } if (onEmpty == null) { throw new ArgumentException("onEmpty"); } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } onKnownSize(sourceCollection.Count); } return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize); } public static int ExceptWith(this ICollection source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } var count = 0; foreach (var item in other) { while (source.Remove(item)) { count++; } } return count; } public static IEnumerable ExceptWithEnumerable(this ICollection source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } foreach (var item in other) { while (source.Remove(item)) { yield return item; } } } public static bool Exists(this IEnumerable source, T value) { if (source == null) { throw new ArgumentNullException("source"); } IEqualityComparer comparer = EqualityComparer.Default; foreach (var local in source) { if (comparer.Equals(local, value)) { return true; } } return false; } public static bool Exists(this IEnumerable source, T value, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } comparer = comparer ?? EqualityComparer.Default; foreach (var local in source) { if (comparer.Equals(local, value)) { return true; } } return false; } public static bool Exists(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } foreach (var item in source) { if (predicate(item)) { return true; } } return false; } public static T Find(this IEnumerable source, int index, int count, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var limit = index + count; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { return enumerator.Current; } currentIndex++; } return default(T); } } public static T Find(this IEnumerable source, int index, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { return enumerator.Current; } currentIndex++; } return default(T); } } public static T Find(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { return enumerator.Current; } } return default(T); } } public static int FindIndex(this IEnumerable source, int index, int count, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var limit = index + count; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { return currentIndex; } currentIndex++; } return -1; } } public static int FindIndex(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { return currentIndex; } currentIndex++; } return -1; } } public static int FindIndex(this IEnumerable source, int index, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { return currentIndex; } currentIndex++; } return -1; } } public static T FindLast(this IEnumerable source, int index, int count, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var limit = index + count; var result = default(T); using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { result = enumerator.Current; } currentIndex++; } return result; } } public static T FindLast(this IEnumerable source, int index, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var result = default(T); using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { result = enumerator.Current; } currentIndex++; } return result; } } public static T FindLast(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var result = default(T); using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { result = enumerator.Current; } } return result; } } public static int FindLastIndex(this IEnumerable source, int index, int count, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var limit = index + count; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { result = currentIndex; } currentIndex++; } return result; } } public static int FindLastIndex(this IEnumerable source, int index, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { result = currentIndex; } currentIndex++; } return result; } } public static int FindLastIndex(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var currentIndex = 0; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { result = currentIndex; } currentIndex++; } return result; } } public static List FindWhere(this IEnumerable source, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var result = new List(); foreach (var item in source) { if (predicate(item)) { result.Add(item); } } return result; } public static TList FindWhere(this IEnumerable source, Predicate predicate) where TList : ICollection, new() { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } var result = new TList(); foreach (var item in source) { if (predicate(item)) { result.Add(item); } } return result; } public static IEnumerable Flatten(this IEnumerable> source) { if (source == null) { throw new ArgumentNullException("source"); } return FlattenExtracted(source); } public static void For(this IEnumerable source, Action action) { if (source == null) { throw new ArgumentNullException("source"); } if (action == null) { throw new ArgumentNullException("action"); } var index = 0; foreach (var item in source) { action.Invoke(index, item); index++; } } public static void For(this IEnumerable source, Action action, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } if (action == null) { throw new ArgumentNullException("action"); } var index = 0; foreach (var item in source) { if (predicate.Invoke(item)) { action.Invoke(index, item); } index++; } } public static void For(this IEnumerable source, Action action, Func filter) { if (source == null) { throw new ArgumentNullException("source"); } if (filter == null) { throw new ArgumentNullException("filter"); } if (action == null) { throw new ArgumentNullException("action"); } var index = 0; foreach (var item in source) { if (filter.Invoke(item, index)) { action.Invoke(index, item); } index++; } } public static void ForEach(this IEnumerable source, Action action) { if (source == null) { throw new ArgumentNullException("source"); } if (action == null) { throw new ArgumentNullException("action"); } foreach (var item in source) { action.Invoke(item); } } public static void ForEach(this IEnumerable source, Action action, Predicate predicate) { if (source == null) { throw new ArgumentNullException("source"); } if (predicate == null) { throw new ArgumentNullException("predicate"); } if (action == null) { throw new ArgumentNullException("action"); } foreach (var item in source) { if (predicate.Invoke(item)) { action.Invoke(item); } } } public static TValue GetOrCreate(this IDictionary dictionary, TKey key) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } TValue value; if (dictionary.TryGetValue(key, out value)) { return value; } var newValue = TypeHelper.CreateOrDefault(); dictionary.Add(key, newValue); return newValue; } public static TValue GetOrCreate(this IDictionary dictionary, TKey key, TValue newValue) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } TValue value; if (dictionary.TryGetValue(key, out value)) { return value; } dictionary.Add(key, newValue); return newValue; } public static TValue GetOrCreate(this IDictionary dictionary, TKey key, Func create) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } TValue value; if (dictionary.TryGetValue(key, out value)) { return value; } var newValue = create == null ? default(TValue) : create(); dictionary.Add(key, newValue); return newValue; } public static int IndexOf(this IEnumerable source, T item, int index, int count) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; var comparer = EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static int IndexOf(this IEnumerable source, T item, int index, int count, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; comparer = comparer ?? EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static int IndexOf(this IEnumerable source, T item, int index) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var comparer = EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static int IndexOf(this IEnumerable source, T item, int index, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; comparer = comparer ?? EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static int IndexOf(this IEnumerable source, T item) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var comparer = EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static int IndexOf(this IEnumerable source, T item, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; comparer = comparer ?? EqualityComparer.Default; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { return currentIndex; } currentIndex++; } return -1; } } public static IEnumerable InterleaveMany(this IEnumerable> source) { if (source == null) { throw new ArgumentNullException("source"); } var enumerators = source.Select(x => x.GetEnumerator()).ToArray(); try { var ok = true; while (ok) { ok = false; foreach (var enumerator in enumerators) { if (enumerator.MoveNext()) { yield return enumerator.Current; ok = true; } } } } finally { foreach (var enumerator in enumerators) { enumerator.Dispose(); } } } public static int IntersectWith(this ICollection source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } var otherAsCollection = AsCollection(other); return source.RemoveWhere(input => !otherAsCollection.Contains(input)); } public static int IntersectWith(this ICollection source, IEnumerable other, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } comparer = comparer ?? EqualityComparer.Default; var otherASCollection = AsCollection(other); return source.RemoveWhere(input => !otherASCollection.Contains(input, comparer)); } public static IEnumerable IntersectWithEnumerable(this ICollection source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } var otherAsCollection = AsCollection(other); return source.RemoveWhereEnumerable(input => !otherAsCollection.Contains(input)); } public static IEnumerable IntersectWithEnumerable(this ICollection source, IEnumerable other, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } comparer = comparer ?? EqualityComparer.Default; var otherAsCollection = AsCollection(other); return source.RemoveWhereEnumerable(input => !otherAsCollection.Contains(input, comparer)); } public static bool IsEmpty(this IEnumerable source) { return !source.Any(); } public static bool IsProperSubsetOf(this IEnumerable source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } return IsSubsetOf(source, other, true); } public static bool IsProperSupersetOf(this IEnumerable source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } return IsSupersetOf(source, other, true); } public static bool IsSubsetOf(this IEnumerable source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } return IsSubsetOf(source, other, false); } public static bool IsSupersetOf(this IEnumerable source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } return IsSupersetOf(source, other, false); } public static int LastIndexOf(this IEnumerable source, T item, int index, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; comparer = comparer ?? EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static int LastIndexOf(this IEnumerable source, T item, int index) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var comparer = EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static int LastIndexOf(this IEnumerable source, T item) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var comparer = EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static int LastIndexOf(this IEnumerable source, T item, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; comparer = comparer ?? EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static int LastIndexOf(this IEnumerable source, T item, int index, int count, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; comparer = comparer ?? EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static int LastIndexOf(this IEnumerable source, T item, int index, int count) { if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; var comparer = EqualityComparer.Default; var result = -1; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (comparer.Equals(enumerator.Current, item)) { result = currentIndex; } currentIndex++; } return result; } } public static bool ListEquals(this ICollection first, ICollection second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. if (first.Count != second.Count) { return false; } var cmp = EqualityComparer.Default; var f = first.GetEnumerator(); var s = second.GetEnumerator(); try { while (f.MoveNext()) { s.MoveNext(); if (!cmp.Equals(f.Current, s.Current)) { return false; } } return true; } finally { f.Dispose(); s.Dispose(); } } // Name needs to be different so it doesn't conflict with Enumerable.Select public static TOutput[] Map(this ICollection source, Func select) { if (source == null) { throw new ArgumentNullException("source"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var count = source.Count; var result = new TOutput[count]; count = 0; foreach (var t in source) { result[count++] = select(t); } return result; } public static void Move(this IList list, int oldIndex, int newIndex) { if (list == null) { throw new ArgumentNullException("list"); } var item = list[oldIndex]; list.RemoveAt(oldIndex); if (newIndex > oldIndex) { newIndex--; } list.Insert(newIndex, item); } public static IEnumerable NullOrEmptyChecked(this IEnumerable source, Action onEmpty) { if (onEmpty == null) { throw new ArgumentException("onEmpty"); } if (source == null) { onEmpty(); return ArrayReservoir.EmptyArray; } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } } return NullOrEmptyCheckedExtracted(source, onEmpty); } public static IEnumerable NullOrEmptyChecked(this IEnumerable source, Action onEmpty, Action onNotEmpty) { if (onEmpty == null) { throw new ArgumentException("onEmpty"); } if (source == null) { onEmpty(); return ArrayReservoir.EmptyArray; } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } onNotEmpty(); } return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty); } public static IEnumerable NullOrEmptyChecked(this IEnumerable source, Action onEmpty, Action onUnknownSize, Action onKnownSize) { if (onEmpty == null) { throw new ArgumentException("onEmpty"); } if (source == null) { onEmpty(); return ArrayReservoir.EmptyArray; } var sourceCollection = source as ICollection; if (sourceCollection != null) { if (sourceCollection.Count == 0) { onEmpty(); return ArrayReservoir.EmptyArray; } onKnownSize(sourceCollection.Count); } return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize); } public static bool Overlaps(this IEnumerable source, IEnumerable items) { return ContainsAny(source, items); } public static IEnumerable Pack(this IEnumerable source, int size) where TPackage : ICollection, new() { if (source == null) { throw new ArgumentNullException("source"); } var count = 0; var currentPackage = new TPackage(); foreach (var item in source) { currentPackage.Add(item); count++; if (count == size) { yield return currentPackage; currentPackage = new TPackage(); count = 0; } } if (count > 0) { yield return currentPackage; } } public static IEnumerable Pack(this IEnumerable source, int size) { if (source == null) { throw new ArgumentNullException("source"); } var index = 0; var currentPackage = new T[size]; foreach (var item in source) { currentPackage[index] = item; index++; if (index == size) { yield return currentPackage; currentPackage = new T[size]; index = 0; } } if (index > 0) { Array.Resize(ref currentPackage, index); yield return currentPackage; } } public static bool Remove(this ICollection source, T item, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } comparer = comparer ?? EqualityComparer.Default; using (var enumerator = source.RemoveWhereEnumerable(input => comparer.Equals(input, item)).GetEnumerator()) { return enumerator.MoveNext(); } } public static T[] RemoveFirst(this T[] array) { if (array == null) { throw new ArgumentNullException("array"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var result = new T[array.Length - 1]; Array.Copy(array, 1, result, 0, result.Length); return result; } public static T[] RemoveLast(this T[] array) { if (array == null) { throw new ArgumentNullException("array"); } // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. var result = new T[array.Length - 1]; Array.Copy(array, 0, result, 0, result.Length); return result; } public static int RemoveWhere(this ICollection source, Predicate predicate) { if (predicate == null) { throw new ArgumentNullException("predicate"); } return RemoveWhere(source, items => Where(items, predicate)); } public static int RemoveWhere(this ICollection source, Func, IEnumerable> converter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } return ExceptWith ( source, new List(converter.Invoke(source)) ); } public static IEnumerable RemoveWhereEnumerable(this ICollection source, Predicate predicate) { if (predicate == null) { throw new ArgumentNullException("predicate"); } return RemoveWhereEnumerable(source, items => Where(items, predicate)); } public static IEnumerable RemoveWhereEnumerable(this ICollection source, Func, IEnumerable> converter) { if (source == null) { throw new ArgumentNullException("source"); } if (converter == null) { throw new ArgumentNullException("converter"); } return ExceptWithEnumerable ( source, new List(converter.Invoke(source)) ); } public static void Reverse(this IList list, int index, int count) { if (list == null) { throw new ArgumentNullException("list"); } if (index < 0) { throw new ArgumentOutOfRangeException("index", "Non-negative number is required."); } if (count < 0) { throw new ArgumentOutOfRangeException("count", "Non-negative number is required."); } var listCount = list.Count; if (count > listCount - index) { throw new ArgumentException("The list does not contain the number of elements.", "list"); } var end = index + count; for (; index < end; index++, end++) { SwapExtracted(list, index, end); } } public static bool SetEquals(this ICollection source, IEnumerable other) { if (source == null) { throw new ArgumentNullException("source"); } if (other == null) { throw new ArgumentNullException("other"); } var thatAsCollection = AsCollection(other); foreach (var item in thatAsCollection.Where(input => !source.Contains(input))) { GC.KeepAlive(item); return false; } foreach (var item in source.Where(input => !thatAsCollection.Contains(input))) { GC.KeepAlive(item); return false; } return true; } public static void Sort(this IList list, int index, int count, IComparer comparer) { if (list == null) { throw new ArgumentNullException("list"); } comparer = comparer ?? Comparer.Default; if (index < 0) { throw new ArgumentOutOfRangeException("index", "Non-negative number is required."); } if (count < 0) { throw new ArgumentOutOfRangeException("count", "Non-negative number is required."); } var listCount = list.Count; if (count > listCount - index) { throw new ArgumentException("The list does not contain the number of elements.", "list"); } SortExtracted(list, index, count + index, comparer); } public static void Swap(this IList list, int indexA, int indexB) { if (list == null) { throw new ArgumentNullException("list"); } if (indexA < 0) { throw new ArgumentOutOfRangeException("indexA", "Non-negative number is required."); } if (indexB < 0) { throw new ArgumentOutOfRangeException("indexB", "Non-negative number is required."); } var listCount = list.Count; if (indexA >= listCount || indexB >= listCount) { throw new ArgumentException("The list does not contain the number of elements.", "list"); } if (indexA != indexB) { SwapExtracted(list, indexA, indexB); } } public static int SymmetricExceptWith(this ICollection source, IEnumerable other) { return source.AddRange(Where(other.Distinct(), input => !source.Remove(input))); } public static IEnumerable SymmetricExceptWithEnumerable(this ICollection source, IEnumerable other) { return source.AddRangeEnumerable(Where(other.Distinct(), input => !source.Remove(input))); } public static T[] ToArray(this ICollection source) { if (source == null) { throw new ArgumentNullException("source"); } return (new List(source)).ToArray(); } public static ReadOnlyCollection ToReadOnly(this IEnumerable source) { if (source == null) { return new ReadOnlyCollection(ArrayReservoir.EmptyArray); } var sourceAsReadOnlyCollection = source as ReadOnlyCollection; if (sourceAsReadOnlyCollection != null) { return sourceAsReadOnlyCollection; } return new ReadOnlyCollection(source.ToArray()); } public static bool TryAdd(this IDictionary dictionary, TKey key, TValue value) { if (dictionary == null) { throw new ArgumentNullException("dictionary"); } try { dictionary.Add(key, value); return true; } catch (ArgumentException ex) { GC.KeepAlive(ex); return false; } } public static bool TryFind(this IEnumerable source, int index, int count, Predicate predicate, out T founT) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { founT = enumerator.Current; return true; } currentIndex++; } founT = default(T); return false; } } public static bool TryFind(this IEnumerable source, int index, Predicate predicate, out T founT) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { founT = enumerator.Current; return true; } currentIndex++; } founT = default(T); return false; } } public static bool TryFind(this IEnumerable source, Predicate predicate, out T founT) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { founT = enumerator.Current; return true; } } founT = default(T); return false; } } public static bool TryFindLast(this IEnumerable source, int index, int count, Predicate predicate, out T foundItem) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; var limit = index + count; foundItem = default(T); var found = false; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (currentIndex == limit) { break; } if (predicate(enumerator.Current)) { foundItem = enumerator.Current; found = true; } currentIndex++; } return found; } } public static bool TryFindLast(this IEnumerable source, int index, Predicate predicate, out T foundItem) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } var currentIndex = 0; foundItem = default(T); var found = false; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { currentIndex++; if (currentIndex == index) { break; } } while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { foundItem = enumerator.Current; found = true; } currentIndex++; } return found; } } public static bool TryFindLast(this IEnumerable source, Predicate predicate, out T foundItem) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } foundItem = default(T); var found = false; using (var enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (predicate(enumerator.Current)) { foundItem = enumerator.Current; found = true; } } return found; } } public static bool TryTake(this Stack stack, out T item) { if (stack == null) { throw new ArgumentNullException("stack"); } try { item = stack.Pop(); return true; } catch (InvalidOperationException) { item = default(T); return false; } } public static bool TryTake(this Queue queue, out T item) { if (queue == null) { throw new ArgumentNullException("queue"); } try { item = queue.Dequeue(); return true; } catch (InvalidOperationException) { item = default(T); return false; } } public static int UnionWith(this ICollection source, IEnumerable other) { return source.AddRange(other.Where(input => !source.Contains(input))); } public static IEnumerable UnionWithEnumerable(this ICollection source, IEnumerable other) { return source.AddRangeEnumerable(other.Where(input => !source.Contains(input))); } public static IEnumerable Where(IEnumerable source, Predicate predicate) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } return WhereExtracted(source, predicate); } public static IEnumerable Where(this IEnumerable source, Func predicate) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } return WhereExtracted(source, predicate); } public static IEnumerable Where(this IEnumerable source, Func predicate, Action whereNot) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } if (whereNot == null) { return WhereExtracted(source, predicate); } return WhereExtracted(source, predicate, whereNot); } public static IEnumerable Where(this IEnumerable source, Func predicate, Action whereNot) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } if (whereNot == null) { return WhereExtracted(source, predicate); } return WhereExtracted(source, predicate, whereNot); } public static IEnumerable Where(this IEnumerable source, Func predicate, Action whereNot) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } if (whereNot == null) { return WhereExtracted(source, predicate); } return WhereExtracted(source, predicate, whereNot); } public static IEnumerable Where(this IEnumerable source, Func predicate, Action whereNot) { if (predicate == null) { throw new ArgumentNullException("predicate"); } if (source == null) { throw new ArgumentNullException("source"); } if (whereNot == null) { return WhereExtracted(source, predicate); } return WhereExtracted(source, predicate, whereNot); } public static IEnumerable WhereType(IEnumerable enumerable) { return new EnumerableFromDelegate(enumerable.GetEnumerator); } public static IEnumerable ZipMany(this IEnumerable> source, Func, TResult> func) { var enumerators = source.Select(x => x.GetEnumerator()).ToArray(); try { while (enumerators.All(enumerator => enumerator.MoveNext())) { yield return func(enumerators.Select(enumerator => enumerator.Current)); } } finally { foreach (var enumerator in enumerators) { enumerator.Dispose(); } } } private static IEnumerable FlattenExtracted(IEnumerable> source) { foreach (var key in source) { foreach (var item in key) { yield return item; } } } private static bool IsSubsetOf(this IEnumerable source, IEnumerable other, bool proper) { var @this = AsDistinctCollection(source); var that = AsDistinctCollection(other); var elementCount = 0; var matchCount = 0; foreach (var item in that) { elementCount++; if (@this.Contains(item)) { matchCount++; } } if (proper) { return matchCount == @this.Count && elementCount > @this.Count; } return matchCount == @this.Count; } private static bool IsSupersetOf(this IEnumerable source, IEnumerable other, bool proper) { var @this = AsDistinctCollection(source); var that = AsDistinctCollection(other); var elementCount = 0; foreach (var item in that) { elementCount++; if (!@this.Contains(item)) { return false; } } if (proper) { return elementCount < @this.Count; } return true; } private static IEnumerable NullOrEmptyCheckedExtracted(IEnumerable source, Action onEmpty) { var enumerator = source.GetEnumerator(); try { if (enumerator.MoveNext()) { yield return enumerator.Current; } else { onEmpty(); yield break; } while (enumerator.MoveNext()) { yield return enumerator.Current; } } finally { enumerator.Dispose(); } } private static IEnumerable NullOrEmptyCheckedExtracted(IEnumerable source, Action onEmpty, Action onNotEmpty) { var enumerator = source.GetEnumerator(); try { if (enumerator.MoveNext()) { onNotEmpty(); yield return enumerator.Current; } else { onEmpty(); yield break; } while (enumerator.MoveNext()) { yield return enumerator.Current; } } finally { enumerator.Dispose(); } } private static void SortExtracted(IList list, int indexStart, int indexEnd, IComparer comparer) { var low = indexStart; var high = indexEnd; var pivot = list[low + ((high - low) / 2)]; while (low <= high) { while (low < indexEnd && comparer.Compare(list[low], pivot) < 0) { low++; } while (high > indexStart && comparer.Compare(pivot, list[high]) < 0) { high--; } if (low == high) { low++; high--; } else if (low < high) { SwapExtracted(list, low, high); low++; high--; } } if (indexStart < high) { SortExtracted(list, indexStart, high, comparer); } if (low < indexEnd) { SortExtracted(list, low, indexEnd, comparer); } } private static void SwapExtracted(IList list, int indexA, int indexB) { var itemA = list[indexA]; var itemB = list[indexB]; list[indexA] = itemB; list[indexB] = itemA; } private static IEnumerable WhereExtracted(IEnumerable source, Predicate predicate) { foreach (var item in source) { if (predicate(item)) { yield return item; } } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate) { var index = 0; foreach (var item in source) { if (predicate(item, index)) { yield return item; } index++; } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate, Action whereNot) { foreach (var item in source) { if (predicate(item)) { yield return item; } else { whereNot(); } } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate) { foreach (var item in source) { if (predicate(item)) { yield return item; } } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate, Action whereNot) { var index = 0; foreach (var item in source) { if (predicate(item, index)) { yield return item; } else { whereNot(); } index++; } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate, Action whereNot) { foreach (var item in source) { if (predicate(item)) { yield return item; } else { whereNot(item); } } } private static IEnumerable WhereExtracted(IEnumerable source, Func predicate, Action whereNot) { var index = 0; foreach (var item in source) { if (predicate(item, index)) { yield return item; } else { whereNot(item); } index++; } } } internal static partial class Extensions { #if NET35 || !NET_4_6 public static bool Contains(this IEnumerable source, IEnumerable items) { if (source == null) { throw new ArgumentNullException("source"); } if (items == null) { throw new ArgumentNullException("items"); } var localComparer = EqualityComparer.Default; var localCollection = AsCollection(source); foreach (var item in items) { if (!localCollection.Contains(item, localComparer)) { return false; } } return true; } public static bool Contains(this IEnumerable source, IEnumerable items, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (items == null) { throw new ArgumentNullException("items"); } var localComparer = comparer ?? EqualityComparer.Default; var localCollection = AsCollection(source); foreach (var item in items) { if (!localCollection.Contains(item, localComparer)) { return false; } } return true; } #endif } } #endif