网上演练
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3098 lines
96 KiB

// 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<T>(this Stack<T> stack, T item)
{
if (stack == null)
{
throw new ArgumentNullException("stack");
}
stack.Push(item);
}
public static void Add<T>(this Queue<T> queue, T item)
{
if (queue == null)
{
throw new ArgumentNullException("queue");
}
queue.Enqueue(item);
}
public static T[] AddFirst<T>(this IList<T> 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<T>(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<T>(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>(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<T> Clone<T>(this IEnumerable<T> target)
{
return new List<T>(target);
}
public static void Consume<T>(this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
foreach (var element in source)
{
GC.KeepAlive(element);
}
}
public static bool ContainsAny<T>(this IEnumerable<T> source, IEnumerable<T> items)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
var localCollection = AsCollection(source);
foreach (var item in items)
{
if (localCollection.Contains(item, comparer))
{
return true;
}
}
return false;
}
public static bool ContainsAny<T>(this IEnumerable<T> source, IEnumerable<T> items, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
comparer = comparer ?? EqualityComparer<T>.Default;
var localCollection = AsCollection(source);
foreach (var item in items)
{
if (localCollection.Contains(item, comparer))
{
return true;
}
}
return false;
}
public static List<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (converter == null)
{
throw new ArgumentNullException("converter");
}
var result = new List<TOutput>();
foreach (var item in source)
{
result.Add(converter(item));
}
return result;
}
public static TList ConvertAll<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter)
where TList : ICollection<TOutput>, 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<TOutput> ConvertFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> 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<TOutput>();
foreach (var item in source)
{
if (filter(item))
{
result.Add(converter(item));
}
}
return result;
}
public static List<TOutput> ConvertFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> 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<TOutput>();
foreach (var item in source)
{
if (filter(item, index))
{
result.Add(converter(item));
}
index++;
}
return result;
}
public static TList ConvertFiltered<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
where TList : ICollection<TOutput>, 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<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
where TList : ICollection<TOutput>, 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<KeyValuePair<int, TOutput>> ConvertIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> 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<KeyValuePair<int, TOutput>>();
foreach (var item in source)
{
if (filter(item))
{
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
}
index++;
}
return result;
}
public static List<KeyValuePair<int, TOutput>> ConvertIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> 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<KeyValuePair<int, TOutput>>();
foreach (var item in source)
{
if (filter(item, index))
{
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
}
index++;
}
return result;
}
public static TList ConvertIndexed<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
where TList : ICollection<KeyValuePair<int, TOutput>>, 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<int, TOutput>(index, converter(item)));
}
index++;
}
return result;
}
public static TList ConvertIndexed<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
where TList : ICollection<KeyValuePair<int, TOutput>>, 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<int, TOutput>(index, converter(item)));
}
index++;
}
return result;
}
public static IEnumerable<TOutput> ConvertProgressive<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> 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<TOutput> ConvertProgressiveFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> 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<TOutput> ConvertProgressiveFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> 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<KeyValuePair<int, TOutput>> ConvertProgressiveIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> 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<int, TOutput>(index, converter(item));
}
index++;
}
}
public static IEnumerable<KeyValuePair<int, TOutput>> ConvertProgressiveIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> 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<int, TOutput>(index, converter(item));
}
index++;
}
}
public static T[] Copy<T>(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<T>(this IEnumerable<T> source, T[] array)
{
CopyTo(source, array, 0);
}
public static void CopyTo<T>(this IEnumerable<T> 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<T>(this IEnumerable<T> source, T[] array, int arrayIndex, int countLimit)
{
CopyTo(source.TakeItems(countLimit), array, arrayIndex);
}
public static int CountContiguousItems<T>(this IEnumerable<T> source, T item)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var result = 0;
var equalityComparer = EqualityComparer<T>.Default;
foreach (var value in source)
{
if (equalityComparer.Equals(value, item))
{
result++;
}
else
{
break;
}
}
return result;
}
public static int CountContiguousItemsWhere<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> 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<T>(this IEnumerable<T> source, T item)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var result = 0;
var equalityComparer = EqualityComparer<T>.Default;
foreach (var value in source)
{
if (equalityComparer.Equals(value, item))
{
result++;
}
}
return result;
}
public static int CountItemsWhere<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> 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<T>(this IEnumerable<T> 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<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
}
return NullOrEmptyCheckedExtracted(source, onEmpty);
}
public static IEnumerable<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onNotEmpty)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
onNotEmpty();
}
return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty);
}
public static IEnumerable<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onUnknownSize, Action<int> onKnownSize)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
onKnownSize(sourceCollection.Count);
}
return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize);
}
public static int ExceptWith<T>(this ICollection<T> source, IEnumerable<T> 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<T> ExceptWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> 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<T>(this IEnumerable<T> source, T value)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
foreach (var local in source)
{
if (comparer.Equals(local, value))
{
return true;
}
}
return false;
}
public static bool Exists<T>(this IEnumerable<T> source, T value, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
comparer = comparer ?? EqualityComparer<T>.Default;
foreach (var local in source)
{
if (comparer.Equals(local, value))
{
return true;
}
}
return false;
}
public static bool Exists<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T> FindWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
var result = new List<T>();
foreach (var item in source)
{
if (predicate(item))
{
result.Add(item);
}
}
return result;
}
public static TList FindWhere<T, TList>(this IEnumerable<T> source, Predicate<T> predicate)
where TList : ICollection<T>, 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<T> Flatten<T>(this IEnumerable<IEnumerable<T>> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return FlattenExtracted(source);
}
public static void For<T>(this IEnumerable<T> source, Action<int, T> 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<T>(this IEnumerable<T> source, Action<int, T> action, Predicate<T> 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<T>(this IEnumerable<T> source, Action<int, T> action, Func<T, int, bool> 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<T>(this IEnumerable<T> source, Action<T> 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<T>(this IEnumerable<T> source, Action<T> action, Predicate<T> 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<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
TValue value;
if (dictionary.TryGetValue(key, out value))
{
return value;
}
var newValue = TypeHelper.CreateOrDefault<TValue>();
dictionary.Add(key, newValue);
return newValue;
}
public static TValue GetOrCreate<TKey, TValue>(this IDictionary<TKey, TValue> 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<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> 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<T>(this IEnumerable<T> source, T item, int index, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var limit = index + count;
var comparer = EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index, int count, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var limit = index + count;
comparer = comparer ?? EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var comparer = EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
comparer = comparer ?? EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var comparer = EqualityComparer<T>.Default;
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (comparer.Equals(enumerator.Current, item))
{
return currentIndex;
}
currentIndex++;
}
return -1;
}
}
public static int IndexOf<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
comparer = comparer ?? EqualityComparer<T>.Default;
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (comparer.Equals(enumerator.Current, item))
{
return currentIndex;
}
currentIndex++;
}
return -1;
}
}
public static IEnumerable<T> InterleaveMany<T>(this IEnumerable<IEnumerable<T>> 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<T>(this ICollection<T> source, IEnumerable<T> 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<T>(this ICollection<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
comparer = comparer ?? EqualityComparer<T>.Default;
var otherASCollection = AsCollection(other);
return source.RemoveWhere(input => !otherASCollection.Contains(input, comparer));
}
public static IEnumerable<T> IntersectWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> 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<T> IntersectWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
comparer = comparer ?? EqualityComparer<T>.Default;
var otherAsCollection = AsCollection(other);
return source.RemoveWhereEnumerable(input => !otherAsCollection.Contains(input, comparer));
}
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
return !source.Any();
}
public static bool IsProperSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
return IsSubsetOf(source, other, true);
}
public static bool IsProperSupersetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
return IsSupersetOf(source, other, true);
}
public static bool IsSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
return IsSubsetOf(source, other, false);
}
public static bool IsSupersetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (other == null)
{
throw new ArgumentNullException("other");
}
return IsSupersetOf(source, other, false);
}
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, int index, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
comparer = comparer ?? EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var comparer = EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var comparer = EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
comparer = comparer ?? EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index, int count, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var limit = index + count;
comparer = comparer ?? EqualityComparer<T>.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<T>(this IEnumerable<T> source, T item, int index, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
var currentIndex = 0;
var limit = index + count;
var comparer = EqualityComparer<T>.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<T>(this ICollection<T> first, ICollection<T> 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<T>.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<TInput, TOutput>(this ICollection<TInput> source, Func<TInput, TOutput> 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<T>(this IList<T> 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<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty)
{
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
if (source == null)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
}
return NullOrEmptyCheckedExtracted(source, onEmpty);
}
public static IEnumerable<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onNotEmpty)
{
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
if (source == null)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
onNotEmpty();
}
return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty);
}
public static IEnumerable<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onUnknownSize, Action<int> onKnownSize)
{
if (onEmpty == null)
{
throw new ArgumentException("onEmpty");
}
if (source == null)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
var sourceCollection = source as ICollection<T>;
if (sourceCollection != null)
{
if (sourceCollection.Count == 0)
{
onEmpty();
return ArrayReservoir<T>.EmptyArray;
}
onKnownSize(sourceCollection.Count);
}
return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize);
}
public static bool Overlaps<T>(this IEnumerable<T> source, IEnumerable<T> items)
{
return ContainsAny(source, items);
}
public static IEnumerable<TPackage> Pack<T, TPackage>(this IEnumerable<T> source, int size)
where TPackage : ICollection<T>, 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<T[]> Pack<T>(this IEnumerable<T> 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<T>(this ICollection<T> source, T item, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
comparer = comparer ?? EqualityComparer<T>.Default;
using (var enumerator = source.RemoveWhereEnumerable(input => comparer.Equals(input, item)).GetEnumerator())
{
return enumerator.MoveNext();
}
}
public static T[] RemoveFirst<T>(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<T>(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<T>(this ICollection<T> source, Predicate<T> predicate)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
return RemoveWhere(source, items => Where(items, predicate));
}
public static int RemoveWhere<T>(this ICollection<T> source, Func<IEnumerable<T>, IEnumerable<T>> converter)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (converter == null)
{
throw new ArgumentNullException("converter");
}
return ExceptWith
(
source,
new List<T>(converter.Invoke(source))
);
}
public static IEnumerable<T> RemoveWhereEnumerable<T>(this ICollection<T> source, Predicate<T> predicate)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
return RemoveWhereEnumerable(source, items => Where(items, predicate));
}
public static IEnumerable<T> RemoveWhereEnumerable<T>(this ICollection<T> source, Func<IEnumerable<T>, IEnumerable<T>> converter)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (converter == null)
{
throw new ArgumentNullException("converter");
}
return ExceptWithEnumerable
(
source,
new List<T>(converter.Invoke(source))
);
}
public static void Reverse<T>(this IList<T> 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<T>(this ICollection<T> source, IEnumerable<T> 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<T>(this IList<T> list, int index, int count, IComparer<T> comparer)
{
if (list == null)
{
throw new ArgumentNullException("list");
}
comparer = comparer ?? Comparer<T>.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<T>(this IList<T> 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<T>(this ICollection<T> source, IEnumerable<T> other)
{
return source.AddRange(Where(other.Distinct(), input => !source.Remove(input)));
}
public static IEnumerable<T> SymmetricExceptWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
{
return source.AddRangeEnumerable(Where(other.Distinct(), input => !source.Remove(input)));
}
public static T[] ToArray<T>(this ICollection<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return (new List<T>(source)).ToArray();
}
public static ReadOnlyCollection<TSource> ToReadOnly<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
return new ReadOnlyCollection<TSource>(ArrayReservoir<TSource>.EmptyArray);
}
var sourceAsReadOnlyCollection = source as ReadOnlyCollection<TSource>;
if (sourceAsReadOnlyCollection != null)
{
return sourceAsReadOnlyCollection;
}
return new ReadOnlyCollection<TSource>(source.ToArray());
}
public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this IEnumerable<T> source, int index, int count, Predicate<T> 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<T>(this IEnumerable<T> source, int index, Predicate<T> 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<T>(this IEnumerable<T> source, Predicate<T> 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<T>(this Stack<T> 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<T>(this Queue<T> 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<T>(this ICollection<T> source, IEnumerable<T> other)
{
return source.AddRange(other.Where(input => !source.Contains(input)));
}
public static IEnumerable<T> UnionWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
{
return source.AddRangeEnumerable(other.Where(input => !source.Contains(input)));
}
public static IEnumerable<T> Where<T>(IEnumerable<T> source, Predicate<T> predicate)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
if (source == null)
{
throw new ArgumentNullException("source");
}
return WhereExtracted(source, predicate);
}
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> predicate)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
if (source == null)
{
throw new ArgumentNullException("source");
}
return WhereExtracted(source, predicate);
}
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> 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<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate, Action<T> 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<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> 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<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> predicate, Action<T> 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<T> WhereType<T>(IEnumerable enumerable)
{
return new EnumerableFromDelegate<T>(enumerable.GetEnumerator);
}
public static IEnumerable<TResult> ZipMany<T, TResult>(this IEnumerable<IEnumerable<T>> source, Func<IEnumerable<T>, 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<T> FlattenExtracted<T>(IEnumerable<IEnumerable<T>> source)
{
foreach (var key in source)
{
foreach (var item in key)
{
yield return item;
}
}
}
private static bool IsSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> 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<T>(this IEnumerable<T> source, IEnumerable<T> 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<T> NullOrEmptyCheckedExtracted<T>(IEnumerable<T> 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<T> NullOrEmptyCheckedExtracted<T>(IEnumerable<T> 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<T>(IList<T> list, int indexStart, int indexEnd, IComparer<T> 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<T>(IList<T> list, int indexA, int indexB)
{
var itemA = list[indexA];
var itemB = list[indexB];
list[indexA] = itemB;
list[indexB] = itemA;
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Predicate<T> predicate)
{
foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate)
{
var index = 0;
foreach (var item in source)
{
if (predicate(item, index))
{
yield return item;
}
index++;
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate, Action whereNot)
{
foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
else
{
whereNot();
}
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate, Action whereNot)
{
var index = 0;
foreach (var item in source)
{
if (predicate(item, index))
{
yield return item;
}
else
{
whereNot();
}
index++;
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate, Action<T> whereNot)
{
foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
else
{
whereNot(item);
}
}
}
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate, Action<T> 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<T>(this IEnumerable<T> source, IEnumerable<T> items)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
var localComparer = EqualityComparer<T>.Default;
var localCollection = AsCollection(source);
foreach (var item in items)
{
if (!localCollection.Contains(item, localComparer))
{
return false;
}
}
return true;
}
public static bool Contains<T>(this IEnumerable<T> source, IEnumerable<T> items, IEqualityComparer<T> comparer)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
var localComparer = comparer ?? EqualityComparer<T>.Default;
var localCollection = AsCollection(source);
foreach (var item in items)
{
if (!localCollection.Contains(item, localComparer))
{
return false;
}
}
return true;
}
#endif
}
}
#endif