Enumerable
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace System.Linq
{
public static class Enumerable
{
private enum Fallback
{
Default,
Throw
}
private static class PredicateOf<T>
{
public static readonly Func<T, bool> Always = (T t) => true;
}
private static class Function<T>
{
public static readonly Func<T, T> Identity = (T t) => t;
}
private static class EmptyOf<T>
{
public static readonly T[] Instance = new T[0];
}
private static class ReadOnlyCollectionOf<T>
{
public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T>(EmptyOf<T>.Instance);
}
public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
{
Check.SourceAndFunc(source, func);
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
if (!enumerator.MoveNext())
throw EmptySequence();
TSource val = enumerator.Current;
while (enumerator.MoveNext()) {
val = func(val, enumerator.Current);
}
return val;
}
}
public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
{
Check.SourceAndFunc(source, func);
TAccumulate val = seed;
foreach (TSource item in source) {
val = func(val, item);
}
return val;
}
public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
{
Check.SourceAndFunc(source, func);
if (resultSelector == null)
throw new ArgumentNullException("resultSelector");
TAccumulate val = seed;
foreach (TSource item in source) {
val = func(val, item);
}
return resultSelector(val);
}
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
foreach (TSource item in source) {
if (!predicate(item))
return false;
}
return true;
}
public static bool Any<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null)
return collection.Count > 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
return enumerator.MoveNext();
}
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
foreach (TSource item in source) {
if (predicate(item))
return true;
}
return false;
}
public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
return source;
}
public static double Average(this IEnumerable<int> source)
{
Check.Source(source);
long num = 0;
int num2 = 0;
foreach (int item in source) {
num = checked(num + item);
num2++;
}
if (num2 == 0)
throw EmptySequence();
return (double)num / (double)num2;
}
public static double Average(this IEnumerable<long> source)
{
Check.Source(source);
long num = 0;
long num2 = 0;
foreach (long item in source) {
num += item;
num2++;
}
if (num2 == 0)
throw EmptySequence();
return (double)num / (double)num2;
}
public static double Average(this IEnumerable<double> source)
{
Check.Source(source);
double num = 0;
long num2 = 0;
foreach (double item in source) {
num += item;
num2++;
}
if (num2 == 0)
throw EmptySequence();
return num / (double)num2;
}
public static float Average(this IEnumerable<float> source)
{
Check.Source(source);
float num = 0;
long num2 = 0;
foreach (float item in source) {
num += item;
num2++;
}
if (num2 == 0)
throw EmptySequence();
return num / (float)num2;
}
public static decimal Average(this IEnumerable<decimal> source)
{
Check.Source(source);
decimal d = default(decimal);
long num = 0;
foreach (decimal item in source) {
d += item;
num++;
}
if (num == 0)
throw EmptySequence();
return d / (decimal)num;
}
private static TResult? AverageNullable<TElement, TAggregate, TResult>(this IEnumerable<TElement?> source, Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result) where TElement : struct where TAggregate : struct where TResult : struct
{
Check.Source(source);
TAggregate arg = default(TAggregate);
long num = 0;
foreach (TElement? item in source) {
if (item.HasValue) {
arg = func(arg, item.Value);
num++;
}
}
if (num == 0)
return null;
return result(arg, num);
}
public static double? Average(this IEnumerable<int?> source)
{
Check.Source(source);
long num = 0;
long num2 = 0;
foreach (int? item in source) {
if (item.HasValue) {
num += item.Value;
num2++;
}
}
if (num2 == 0)
return null;
return (double)num / (double)num2;
}
public static double? Average(this IEnumerable<long?> source)
{
Check.Source(source);
long num = 0;
long num2 = 0;
foreach (long? item in source) {
if (item.HasValue) {
num = checked(num + item.Value);
num2++;
}
}
if (num2 == 0)
return null;
return (double)num / (double)num2;
}
public static double? Average(this IEnumerable<double?> source)
{
Check.Source(source);
double num = 0;
long num2 = 0;
foreach (double? item in source) {
if (item.HasValue) {
num += item.Value;
num2++;
}
}
if (num2 == 0)
return null;
return num / (double)num2;
}
public static decimal? Average(this IEnumerable<decimal?> source)
{
Check.Source(source);
decimal d = default(decimal);
long num = 0;
foreach (decimal? item in source) {
if (item.HasValue) {
d += item.Value;
num++;
}
}
if (num == 0)
return null;
return d / (decimal)num;
}
public static float? Average(this IEnumerable<float?> source)
{
Check.Source(source);
float num = 0;
long num2 = 0;
foreach (float? item in source) {
if (item.HasValue) {
num += item.Value;
num2++;
}
}
if (num2 == 0)
return null;
return num / (float)num2;
}
public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
long num2 = 0;
foreach (TSource item in source) {
num += selector(item);
num2++;
}
if (num2 == 0)
throw EmptySequence();
return (double)num / (double)num2;
}
public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
long num2 = 0;
foreach (TSource item in source) {
int? nullable = selector(item);
if (nullable.HasValue) {
num += nullable.Value;
num2++;
}
}
if (num2 == 0)
return null;
return (double)num / (double)num2;
}
public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
long num2 = 0;
foreach (TSource item in source) {
num = checked(num + selector(item));
num2++;
}
if (num2 == 0)
throw EmptySequence();
return (double)num / (double)num2;
}
public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
long num2 = 0;
foreach (TSource item in source) {
long? nullable = selector(item);
if (nullable.HasValue) {
num = checked(num + nullable.Value);
num2++;
}
}
if (num2 == 0)
return null;
return (double)num / (double)num2;
}
public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
{
Check.SourceAndSelector(source, selector);
double num = 0;
long num2 = 0;
foreach (TSource item in source) {
num += selector(item);
num2++;
}
if (num2 == 0)
throw EmptySequence();
return num / (double)num2;
}
public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
{
Check.SourceAndSelector(source, selector);
double num = 0;
long num2 = 0;
foreach (TSource item in source) {
double? nullable = selector(item);
if (nullable.HasValue) {
num += nullable.Value;
num2++;
}
}
if (num2 == 0)
return null;
return num / (double)num2;
}
public static float Average<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector)
{
Check.SourceAndSelector(source, selector);
float num = 0;
long num2 = 0;
foreach (TSource item in source) {
num += selector(item);
num2++;
}
if (num2 == 0)
throw EmptySequence();
return num / (float)num2;
}
public static float? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector)
{
Check.SourceAndSelector(source, selector);
float num = 0;
long num2 = 0;
foreach (TSource item in source) {
float? nullable = selector(item);
if (nullable.HasValue) {
num += nullable.Value;
num2++;
}
}
if (num2 == 0)
return null;
return num / (float)num2;
}
public static decimal Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
Check.SourceAndSelector(source, selector);
decimal d = default(decimal);
long num = 0;
foreach (TSource item in source) {
d += selector(item);
num++;
}
if (num == 0)
throw EmptySequence();
return d / (decimal)num;
}
public static decimal? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
Check.SourceAndSelector(source, selector);
decimal d = default(decimal);
long num = 0;
foreach (TSource item in source) {
decimal? nullable = selector(item);
if (nullable.HasValue) {
d += nullable.Value;
num++;
}
}
if (num == 0)
return null;
return d / (decimal)num;
}
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
Check.Source(source);
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if (enumerable != null)
return enumerable;
return CreateCastIterator<TResult>(source);
}
private static IEnumerable<TResult> CreateCastIterator<TResult>(IEnumerable source)
{
foreach (TResult item in source) {
yield return item;
}
}
public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
Check.FirstAndSecond(first, second);
return CreateConcatIterator(first, second);
}
private static IEnumerable<TSource> CreateConcatIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second)
{
foreach (TSource item in first) {
yield return item;
}
foreach (TSource item2 in second) {
yield return item2;
}
}
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value)
{
return (source as ICollection<TSource>)?.Contains(value) ?? source.Contains(value, null);
}
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
{
Check.Source(source);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
foreach (TSource item in source) {
if (comparer.Equals(item, value))
return true;
}
return false;
}
public static int Count<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null)
return collection.Count;
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
num = checked(num + 1);
}
return num;
}
}
public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndSelector(source, predicate);
int num = 0;
foreach (TSource item in source) {
if (predicate(item))
num = checked(num + 1);
}
return num;
}
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source)
{
return source.DefaultIfEmpty(default(TSource));
}
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
{
Check.Source(source);
return CreateDefaultIfEmptyIterator(source, defaultValue);
}
private static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue)
{
bool empty = true;
foreach (TSource item in source) {
empty = false;
yield return item;
}
if (empty)
yield return defaultValue;
}
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source)
{
return source.Distinct(null);
}
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
Check.Source(source);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
return CreateDistinctIterator(source, comparer);
}
private static IEnumerable<TSource> CreateDistinctIterator<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
HashSet<TSource> items = new HashSet<TSource>(comparer);
foreach (TSource item in source) {
if (!items.Contains(item)) {
items.Add(item);
yield return item;
}
}
}
private static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index, Fallback fallback)
{
long num = 0;
foreach (TSource item in source) {
long num2 = index;
long num3 = num;
num = num3 + 1;
if (num2 == num3)
return item;
}
if (fallback == Fallback.Throw)
throw new ArgumentOutOfRangeException();
return default(TSource);
}
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
Check.Source(source);
if (index < 0)
throw new ArgumentOutOfRangeException();
IList<TSource> list = source as IList<TSource>;
if (list != null)
return list[index];
return source.ElementAt(index, Fallback.Throw);
}
public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
{
Check.Source(source);
if (index < 0)
return default(TSource);
IList<TSource> list = source as IList<TSource>;
if (list != null) {
if (index >= ((ICollection<TSource>)list).Count)
return default(TSource);
return list[index];
}
return source.ElementAt(index, Fallback.Default);
}
public static IEnumerable<TResult> Empty<TResult>()
{
return EmptyOf<TResult>.Instance;
}
public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
return first.Except(second, null);
}
public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
Check.FirstAndSecond(first, second);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
return CreateExceptIterator(first, second, comparer);
}
private static IEnumerable<TSource> CreateExceptIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
HashSet<TSource> items = new HashSet<TSource>(second, comparer);
foreach (TSource item in first) {
if (items.Add(item))
yield return item;
}
}
private static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
{
foreach (TSource item in source) {
if (predicate(item))
return item;
}
if (fallback == Fallback.Throw)
throw NoMatchingElement();
return default(TSource);
}
public static TSource First<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
IList<TSource> list = source as IList<TSource>;
if (list != null) {
if (((ICollection<TSource>)list).Count != 0)
return list[0];
} else {
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
if (enumerator.MoveNext())
return enumerator.Current;
}
}
throw EmptySequence();
}
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.First(predicate, Fallback.Throw);
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
return source.First(PredicateOf<TSource>.Always, Fallback.Default);
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.First(predicate, Fallback.Default);
}
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.GroupBy(keySelector, null);
}
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
Check.SourceAndKeySelector(source, keySelector);
return source.CreateGroupByIterator(keySelector, comparer);
}
private static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>>(comparer);
List<TSource> nullList = new List<TSource>();
int counter2 = 0;
int nullCounter = -1;
foreach (TSource item in source) {
TKey val = keySelector(item);
if (val == null) {
nullList.Add(item);
if (nullCounter == -1) {
nullCounter = counter2;
counter2++;
}
} else {
if (!dictionary.TryGetValue(val, out List<TSource> value)) {
value = new List<TSource>();
dictionary.Add(val, value);
counter2++;
}
value.Add(item);
}
}
counter2 = 0;
Dictionary<TKey, List<TSource>>.Enumerator enumerator2 = dictionary.GetEnumerator();
try {
while (enumerator2.MoveNext()) {
KeyValuePair<TKey, List<TSource>> group = enumerator2.Current;
if (counter2 == nullCounter) {
yield return (IGrouping<TKey, TSource>)new Grouping<TKey, TSource>(default(TKey), (IEnumerable<TSource>)nullList);
counter2++;
}
yield return (IGrouping<TKey, TSource>)new Grouping<TKey, TSource>(group.Key, (IEnumerable<TSource>)group.Value);
counter2++;
group = default(KeyValuePair<TKey, List<TSource>>);
}
} finally {
((IDisposable)enumerator2).Dispose();
}
enumerator2 = default(Dictionary<TKey, List<TSource>>.Enumerator);
if (counter2 == nullCounter)
yield return (IGrouping<TKey, TSource>)new Grouping<TKey, TSource>(default(TKey), (IEnumerable<TSource>)nullList);
}
public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
{
return source.GroupBy(keySelector, elementSelector, null);
}
public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{
Check.SourceAndKeyElementSelectors(source, keySelector, elementSelector);
return source.CreateGroupByIterator(keySelector, elementSelector, comparer);
}
private static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{
Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>>(comparer);
List<TElement> nullList = new List<TElement>();
int counter2 = 0;
int nullCounter = -1;
foreach (TSource item2 in source) {
TKey val = keySelector(item2);
TElement item = elementSelector(item2);
if (val == null) {
nullList.Add(item);
if (nullCounter == -1) {
nullCounter = counter2;
counter2++;
}
} else {
if (!dictionary.TryGetValue(val, out List<TElement> value)) {
value = new List<TElement>();
dictionary.Add(val, value);
counter2++;
}
value.Add(item);
}
}
counter2 = 0;
Dictionary<TKey, List<TElement>>.Enumerator enumerator2 = dictionary.GetEnumerator();
try {
while (enumerator2.MoveNext()) {
KeyValuePair<TKey, List<TElement>> group = enumerator2.Current;
if (counter2 == nullCounter) {
yield return (IGrouping<TKey, TElement>)new Grouping<TKey, TElement>(default(TKey), (IEnumerable<TElement>)nullList);
counter2++;
}
yield return (IGrouping<TKey, TElement>)new Grouping<TKey, TElement>(group.Key, (IEnumerable<TElement>)group.Value);
counter2++;
group = default(KeyValuePair<TKey, List<TElement>>);
}
} finally {
((IDisposable)enumerator2).Dispose();
}
enumerator2 = default(Dictionary<TKey, List<TElement>>.Enumerator);
if (counter2 == nullCounter)
yield return (IGrouping<TKey, TElement>)new Grouping<TKey, TElement>(default(TKey), (IEnumerable<TElement>)nullList);
}
public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
{
return source.GroupBy(keySelector, elementSelector, resultSelector, null);
}
public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
Check.GroupBySelectors(source, keySelector, elementSelector, resultSelector);
return source.CreateGroupByIterator(keySelector, elementSelector, resultSelector, comparer);
}
private static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
IEnumerable<IGrouping<TKey, TElement>> enumerable = Enumerable.GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
foreach (IGrouping<TKey, TElement> item in enumerable) {
yield return resultSelector(item.Key, item);
}
}
public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
{
return source.GroupBy(keySelector, resultSelector, null);
}
public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
Check.SourceAndKeyResultSelectors(source, keySelector, resultSelector);
return source.CreateGroupByIterator(keySelector, resultSelector, comparer);
}
private static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
IEnumerable<IGrouping<TKey, TSource>> enumerable = Enumerable.GroupBy<TSource, TKey>(source, keySelector, comparer);
foreach (IGrouping<TKey, TSource> item in enumerable) {
yield return resultSelector(item.Key, item);
}
}
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
{
return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, null);
}
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
Check.JoinSelectors(outer, inner, outerKeySelector, innerKeySelector, resultSelector);
if (comparer == null)
comparer = EqualityComparer<TKey>.Default;
return outer.CreateGroupJoinIterator(inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
}
private static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
ILookup<TKey, TInner> innerKeys = Enumerable.ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);
foreach (TOuter item in outer) {
TKey val = outerKeySelector(item);
if (val != null && innerKeys.Contains(val))
yield return resultSelector(item, innerKeys[val]);
else
yield return resultSelector(item, Enumerable.Empty<TInner>());
}
}
public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
return first.Intersect(second, null);
}
public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
Check.FirstAndSecond(first, second);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
return CreateIntersectIterator(first, second, comparer);
}
private static IEnumerable<TSource> CreateIntersectIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
HashSet<TSource> items = new HashSet<TSource>(second, comparer);
foreach (TSource item in first) {
if (items.Remove(item))
yield return item;
}
}
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
Check.JoinSelectors(outer, inner, outerKeySelector, innerKeySelector, resultSelector);
if (comparer == null)
comparer = EqualityComparer<TKey>.Default;
return outer.CreateJoinIterator(inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
}
private static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{
ILookup<TKey, TInner> innerKeys = Enumerable.ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);
foreach (TOuter item in outer) {
TKey val = outerKeySelector(item);
if (val != null && innerKeys.Contains(val)) {
foreach (TInner item2 in innerKeys[val]) {
yield return resultSelector(item, item2);
}
}
}
}
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
{
return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, null);
}
private static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
{
bool flag = true;
TSource result = default(TSource);
foreach (TSource item in source) {
if (predicate(item)) {
result = item;
flag = false;
}
}
if (!flag)
return result;
if (fallback == Fallback.Throw)
throw NoMatchingElement();
return result;
}
public static TSource Last<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null && collection.Count == 0)
throw EmptySequence();
IList<TSource> list = source as IList<TSource>;
if (list != null)
return list[((ICollection<TSource>)list).Count - 1];
return source.Last(PredicateOf<TSource>.Always, Fallback.Throw);
}
public static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.Last(predicate, Fallback.Throw);
}
public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
IList<TSource> list = source as IList<TSource>;
if (list != null) {
if (((ICollection<TSource>)list).Count <= 0)
return default(TSource);
return list[((ICollection<TSource>)list).Count - 1];
}
return source.Last(PredicateOf<TSource>.Always, Fallback.Default);
}
public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.Last(predicate, Fallback.Default);
}
public static long LongCount<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
TSource[] array = source as TSource[];
if (array != null)
return array.LongLength;
long num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
while (enumerator.MoveNext()) {
num++;
}
return num;
}
}
public static long LongCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndSelector(source, predicate);
long num = 0;
foreach (TSource item in source) {
if (predicate(item))
num++;
}
return num;
}
public static int Max(this IEnumerable<int> source)
{
Check.Source(source);
bool flag = true;
int num = -2147483648;
foreach (int item in source) {
num = Math.Max(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static long Max(this IEnumerable<long> source)
{
Check.Source(source);
bool flag = true;
long num = -9223372036854775808;
foreach (long item in source) {
num = Math.Max(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static double Max(this IEnumerable<double> source)
{
Check.Source(source);
bool flag = true;
double num = -1.7976931348623157E+308;
foreach (double item in source) {
num = Math.Max(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static float Max(this IEnumerable<float> source)
{
Check.Source(source);
bool flag = true;
float num = -3.4028235E+38;
foreach (float item in source) {
num = Math.Max(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static decimal Max(this IEnumerable<decimal> source)
{
Check.Source(source);
bool flag = true;
decimal num = decimal.MinValue;
foreach (decimal item in source) {
num = Math.Max(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static int? Max(this IEnumerable<int?> source)
{
Check.Source(source);
bool flag = true;
int num = -2147483648;
foreach (int? item in source) {
if (item.HasValue) {
num = Math.Max(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static long? Max(this IEnumerable<long?> source)
{
Check.Source(source);
bool flag = true;
long num = -9223372036854775808;
foreach (long? item in source) {
if (item.HasValue) {
num = Math.Max(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static double? Max(this IEnumerable<double?> source)
{
Check.Source(source);
bool flag = true;
double num = -1.7976931348623157E+308;
foreach (double? item in source) {
if (item.HasValue) {
num = Math.Max(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static float? Max(this IEnumerable<float?> source)
{
Check.Source(source);
bool flag = true;
float num = -3.4028235E+38;
foreach (float? item in source) {
if (item.HasValue) {
num = Math.Max(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static decimal? Max(this IEnumerable<decimal?> source)
{
Check.Source(source);
bool flag = true;
decimal num = decimal.MinValue;
foreach (decimal? item in source) {
if (item.HasValue) {
num = Math.Max(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static TSource Max<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
Comparer<TSource> default = Comparer<TSource>.Default;
TSource val = default(TSource);
if (default(TSource) == null) {
foreach (TSource item in source) {
if (item != null && (val == null || default.Compare(item, val) > 0))
val = item;
}
return val;
}
bool flag = true;
foreach (TSource item2 in source) {
if (flag) {
val = item2;
flag = false;
} else if (default.Compare(item2, val) > 0) {
val = item2;
}
}
if (flag)
throw EmptySequence();
return val;
}
public static int Max<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
int num = -2147483648;
foreach (TSource item in source) {
num = Math.Max(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static long Max<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
long num = -9223372036854775808;
foreach (TSource item in source) {
num = Math.Max(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static double Max<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
double num = -1.7976931348623157E+308;
foreach (TSource item in source) {
num = Math.Max(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static float Max<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
float num = -3.4028235E+38;
foreach (TSource item in source) {
num = Math.Max(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static decimal Max<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
decimal num = decimal.MinValue;
foreach (TSource item in source) {
num = Math.Max(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
private static U Iterate<T, U>(IEnumerable<T> source, U initValue, Func<T, U, U> selector)
{
bool flag = true;
foreach (T item in source) {
initValue = selector(item, initValue);
flag = false;
}
if (flag)
throw NoMatchingElement();
return initValue;
}
public static int? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
int? nullable = null;
foreach (TSource item in source) {
int? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 > nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static long? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
long? nullable = null;
foreach (TSource item in source) {
long? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 > nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static double? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
double? nullable = null;
foreach (TSource item in source) {
double? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 > nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static float? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
float? nullable = null;
foreach (TSource item in source) {
float? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 > nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static decimal? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
decimal? nullable = null;
foreach (TSource item in source) {
decimal? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 > nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
Check.SourceAndSelector(source, selector);
return source.Select(selector).Max();
}
public static int Min(this IEnumerable<int> source)
{
Check.Source(source);
bool flag = true;
int num = 2147483647;
foreach (int item in source) {
num = Math.Min(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static long Min(this IEnumerable<long> source)
{
Check.Source(source);
bool flag = true;
long num = 9223372036854775807;
foreach (long item in source) {
num = Math.Min(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static double Min(this IEnumerable<double> source)
{
Check.Source(source);
bool flag = true;
double num = 1.7976931348623157E+308;
foreach (double item in source) {
num = Math.Min(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static float Min(this IEnumerable<float> source)
{
Check.Source(source);
bool flag = true;
float num = 3.4028235E+38;
foreach (float item in source) {
num = Math.Min(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static decimal Min(this IEnumerable<decimal> source)
{
Check.Source(source);
bool flag = true;
decimal num = decimal.MaxValue;
foreach (decimal item in source) {
num = Math.Min(item, num);
flag = false;
}
if (flag)
throw EmptySequence();
return num;
}
public static int? Min(this IEnumerable<int?> source)
{
Check.Source(source);
bool flag = true;
int num = 2147483647;
foreach (int? item in source) {
if (item.HasValue) {
num = Math.Min(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static long? Min(this IEnumerable<long?> source)
{
Check.Source(source);
bool flag = true;
long num = 9223372036854775807;
foreach (long? item in source) {
if (item.HasValue) {
num = Math.Min(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static double? Min(this IEnumerable<double?> source)
{
Check.Source(source);
bool flag = true;
double num = 1.7976931348623157E+308;
foreach (double? item in source) {
if (item.HasValue) {
num = Math.Min(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static float? Min(this IEnumerable<float?> source)
{
Check.Source(source);
bool flag = true;
float num = 3.4028235E+38;
foreach (float? item in source) {
if (item.HasValue) {
num = Math.Min(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static decimal? Min(this IEnumerable<decimal?> source)
{
Check.Source(source);
bool flag = true;
decimal num = decimal.MaxValue;
foreach (decimal? item in source) {
if (item.HasValue) {
num = Math.Min(item.Value, num);
flag = false;
}
}
if (flag)
return null;
return num;
}
public static TSource Min<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
Comparer<TSource> default = Comparer<TSource>.Default;
TSource val = default(TSource);
if (default(TSource) == null) {
foreach (TSource item in source) {
if (item != null && (val == null || default.Compare(item, val) < 0))
val = item;
}
return val;
}
bool flag = true;
foreach (TSource item2 in source) {
if (flag) {
val = item2;
flag = false;
} else if (default.Compare(item2, val) < 0) {
val = item2;
}
}
if (flag)
throw EmptySequence();
return val;
}
public static int Min<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
int num = 2147483647;
foreach (TSource item in source) {
num = Math.Min(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static long Min<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
long num = 9223372036854775807;
foreach (TSource item in source) {
num = Math.Min(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static double Min<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
double num = 1.7976931348623157E+308;
foreach (TSource item in source) {
num = Math.Min(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static float Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
float num = 3.4028235E+38;
foreach (TSource item in source) {
num = Math.Min(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static decimal Min<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
decimal num = decimal.MaxValue;
foreach (TSource item in source) {
num = Math.Min(selector(item), num);
flag = false;
}
if (flag)
throw NoMatchingElement();
return num;
}
public static int? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
int? nullable = null;
foreach (TSource item in source) {
int? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 < nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static long? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
long? nullable = null;
foreach (TSource item in source) {
long? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 < nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static float? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
float? nullable = null;
foreach (TSource item in source) {
float? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 < nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static double? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
double? nullable = null;
foreach (TSource item in source) {
double? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 < nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static decimal? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
Check.SourceAndSelector(source, selector);
bool flag = true;
decimal? nullable = null;
foreach (TSource item in source) {
decimal? nullable2 = selector(item);
if (!nullable.HasValue)
nullable = nullable2;
else if (nullable2 < nullable) {
nullable = nullable2;
}
flag = false;
}
if (flag)
return null;
return nullable;
}
public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
Check.SourceAndSelector(source, selector);
return source.Select(selector).Min();
}
public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source)
{
Check.Source(source);
return CreateOfTypeIterator<TResult>(source);
}
private static IEnumerable<TResult> CreateOfTypeIterator<TResult>(IEnumerable source)
{
foreach (object item in source) {
if (item is TResult)
yield return (TResult)item;
}
}
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.OrderBy(keySelector, null);
}
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
Check.SourceAndKeySelector(source, keySelector);
return new OrderedSequence<TSource, TKey>(source, keySelector, comparer, SortDirection.Ascending);
}
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.OrderByDescending(keySelector, null);
}
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
Check.SourceAndKeySelector(source, keySelector);
return new OrderedSequence<TSource, TKey>(source, keySelector, comparer, SortDirection.Descending);
}
public static IEnumerable<int> Range(int start, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException("count");
if ((long)start + (long)count - 1 > 2147483647)
throw new ArgumentOutOfRangeException();
return CreateRangeIterator(start, count);
}
private static IEnumerable<int> CreateRangeIterator(int start, int count)
{
for (int i = 0; i < count; i++) {
yield return start + i;
}
}
public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
return CreateRepeatIterator(element, count);
}
private static IEnumerable<TResult> CreateRepeatIterator<TResult>(TResult element, int count)
{
for (int i = 0; i < count; i++) {
yield return element;
}
}
public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
return CreateReverseIterator(source);
}
private static IEnumerable<TSource> CreateReverseIterator<TSource>(IEnumerable<TSource> source)
{
TSource[] array = Enumerable.ToArray<TSource>(source);
for (int i = array.Length - 1; i >= 0; i--) {
yield return array[i];
}
}
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
Check.SourceAndSelector(source, selector);
return CreateSelectIterator(source, selector);
}
private static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
foreach (TSource item in source) {
yield return selector(item);
}
}
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
Check.SourceAndSelector(source, selector);
return CreateSelectIterator(source, selector);
}
private static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
int counter = 0;
foreach (TSource item in source) {
yield return selector(item, counter);
counter++;
}
}
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
{
Check.SourceAndSelector(source, selector);
return CreateSelectManyIterator(source, selector);
}
private static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
{
foreach (TSource item in source) {
foreach (TResult item2 in selector(item)) {
yield return item2;
}
}
}
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
{
Check.SourceAndSelector(source, selector);
return CreateSelectManyIterator(source, selector);
}
private static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
{
int counter = 0;
foreach (TSource item in source) {
foreach (TResult item2 in selector(item, counter)) {
yield return item2;
}
counter++;
}
}
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
Check.SourceAndCollectionSelectors(source, collectionSelector, resultSelector);
return CreateSelectManyIterator(source, collectionSelector, resultSelector);
}
private static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
{
foreach (TSource item in source) {
foreach (TCollection item2 in collectionSelector(item)) {
yield return selector(item, item2);
}
}
}
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
Check.SourceAndCollectionSelectors(source, collectionSelector, resultSelector);
return CreateSelectManyIterator(source, collectionSelector, resultSelector);
}
private static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
{
int counter = 0;
foreach (TSource item in source) {
TSource arg = item;
int num = counter;
counter = num + 1;
foreach (TCollection item2 in collectionSelector(arg, num)) {
yield return selector(item, item2);
}
}
}
private static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
{
bool flag = false;
TSource result = default(TSource);
foreach (TSource item in source) {
if (predicate(item)) {
if (flag)
throw MoreThanOneMatchingElement();
flag = true;
result = item;
}
}
if (!flag && fallback == Fallback.Throw)
throw NoMatchingElement();
return result;
}
public static TSource Single<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
return source.Single(PredicateOf<TSource>.Always, Fallback.Throw);
}
public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.Single(predicate, Fallback.Throw);
}
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
return source.Single(PredicateOf<TSource>.Always, Fallback.Default);
}
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return source.Single(predicate, Fallback.Default);
}
public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)
{
Check.Source(source);
return CreateSkipIterator(source, count);
}
private static IEnumerable<TSource> CreateSkipIterator<TSource>(IEnumerable<TSource> source, int count)
{
IEnumerator<TSource> enumerator = source.GetEnumerator();
try {
while (true) {
int num = count;
count = num - 1;
if (num <= 0)
break;
if (!enumerator.MoveNext())
yield break;
}
while (enumerator.MoveNext()) {
yield return enumerator.Current;
}
} finally {
enumerator.Dispose();
}
}
public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return CreateSkipWhileIterator(source, predicate);
}
private static IEnumerable<TSource> CreateSkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
bool yield = false;
foreach (TSource item in source) {
if (yield)
yield return item;
else if (!predicate(item)) {
yield return item;
yield = true;
}
}
}
public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return CreateSkipWhileIterator(source, predicate);
}
private static IEnumerable<TSource> CreateSkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
int counter = 0;
bool yield = false;
foreach (TSource item in source) {
if (yield)
yield return item;
else if (!predicate(item, counter)) {
yield return item;
yield = true;
}
counter++;
}
}
public static int Sum(this IEnumerable<int> source)
{
Check.Source(source);
int num = 0;
foreach (int item in source) {
num = checked(num + item);
}
return num;
}
public static int? Sum(this IEnumerable<int?> source)
{
Check.Source(source);
int num = 0;
foreach (int? item in source) {
if (item.HasValue)
num = checked(num + item.Value);
}
return num;
}
public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
Check.SourceAndSelector(source, selector);
int num = 0;
foreach (TSource item in source) {
num = checked(num + selector(item));
}
return num;
}
public static int? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
{
Check.SourceAndSelector(source, selector);
int num = 0;
foreach (TSource item in source) {
int? nullable = selector(item);
if (nullable.HasValue)
num = checked(num + nullable.Value);
}
return num;
}
public static long Sum(this IEnumerable<long> source)
{
Check.Source(source);
long num = 0;
foreach (long item in source) {
num = checked(num + item);
}
return num;
}
public static long? Sum(this IEnumerable<long?> source)
{
Check.Source(source);
long num = 0;
foreach (long? item in source) {
if (item.HasValue)
num = checked(num + item.Value);
}
return num;
}
public static long Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
foreach (TSource item in source) {
num = checked(num + selector(item));
}
return num;
}
public static long? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
{
Check.SourceAndSelector(source, selector);
long num = 0;
foreach (TSource item in source) {
long? nullable = selector(item);
if (nullable.HasValue)
num = checked(num + nullable.Value);
}
return num;
}
public static double Sum(this IEnumerable<double> source)
{
Check.Source(source);
double num = 0;
foreach (double item in source) {
num += item;
}
return num;
}
public static double? Sum(this IEnumerable<double?> source)
{
Check.Source(source);
double num = 0;
foreach (double? item in source) {
if (item.HasValue)
num += item.Value;
}
return num;
}
public static double Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
{
Check.SourceAndSelector(source, selector);
double num = 0;
foreach (TSource item in source) {
num += selector(item);
}
return num;
}
public static double? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
{
Check.SourceAndSelector(source, selector);
double num = 0;
foreach (TSource item in source) {
double? nullable = selector(item);
if (nullable.HasValue)
num += nullable.Value;
}
return num;
}
public static float Sum(this IEnumerable<float> source)
{
Check.Source(source);
float num = 0;
foreach (float item in source) {
num += item;
}
return num;
}
public static float? Sum(this IEnumerable<float?> source)
{
Check.Source(source);
float num = 0;
foreach (float? item in source) {
if (item.HasValue)
num += item.Value;
}
return num;
}
public static float Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector)
{
Check.SourceAndSelector(source, selector);
float num = 0;
foreach (TSource item in source) {
num += selector(item);
}
return num;
}
public static float? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector)
{
Check.SourceAndSelector(source, selector);
float num = 0;
foreach (TSource item in source) {
float? nullable = selector(item);
if (nullable.HasValue)
num += nullable.Value;
}
return num;
}
public static decimal Sum(this IEnumerable<decimal> source)
{
Check.Source(source);
decimal num = default(decimal);
foreach (decimal item in source) {
num += item;
}
return num;
}
public static decimal? Sum(this IEnumerable<decimal?> source)
{
Check.Source(source);
decimal num = default(decimal);
foreach (decimal? item in source) {
if (item.HasValue)
num += item.Value;
}
return num;
}
public static decimal Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
Check.SourceAndSelector(source, selector);
decimal num = default(decimal);
foreach (TSource item in source) {
num += selector(item);
}
return num;
}
public static decimal? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
{
Check.SourceAndSelector(source, selector);
decimal num = default(decimal);
foreach (TSource item in source) {
decimal? nullable = selector(item);
if (nullable.HasValue)
num += nullable.Value;
}
return num;
}
public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, int count)
{
Check.Source(source);
return CreateTakeIterator(source, count);
}
private static IEnumerable<TSource> CreateTakeIterator<TSource>(IEnumerable<TSource> source, int count)
{
if (count > 0) {
int counter = 0;
foreach (TSource item in source) {
yield return item;
int num = counter + 1;
counter = num;
if (num == count)
yield break;
}
}
}
public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return CreateTakeWhileIterator(source, predicate);
}
private static IEnumerable<TSource> CreateTakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource item in source) {
if (!predicate(item))
yield break;
yield return item;
}
}
public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
return CreateTakeWhileIterator(source, predicate);
}
private static IEnumerable<TSource> CreateTakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
int counter = 0;
foreach (TSource item in source) {
if (!predicate(item, counter))
yield break;
yield return item;
counter++;
}
}
public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.ThenBy(keySelector, null);
}
public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
Check.SourceAndKeySelector(source, keySelector);
return source.CreateOrderedEnumerable(keySelector, comparer, false);
}
public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.ThenByDescending(keySelector, null);
}
public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
Check.SourceAndKeySelector(source, keySelector);
return source.CreateOrderedEnumerable(keySelector, comparer, true);
}
public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
ICollection<TSource> collection = source as ICollection<TSource>;
TSource[] array;
if (collection != null) {
if (collection.Count == 0)
return EmptyOf<TSource>.Instance;
array = new TSource[collection.Count];
collection.CopyTo(array, 0);
return array;
}
int num = 0;
array = EmptyOf<TSource>.Instance;
foreach (TSource item in source) {
if (num == array.Length) {
if (num == 0)
array = new TSource[4];
else
Array.Resize(ref array, num * 2);
}
array[num++] = item;
}
if (num != array.Length)
Array.Resize(ref array, num);
return array;
}
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
{
return source.ToDictionary(keySelector, elementSelector, null);
}
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{
Check.SourceAndKeyElementSelectors(source, keySelector, elementSelector);
if (comparer == null)
comparer = EqualityComparer<TKey>.Default;
Dictionary<TKey, TElement> dictionary = new Dictionary<TKey, TElement>(comparer);
foreach (TSource item in source) {
dictionary.Add(keySelector(item), elementSelector(item));
}
return dictionary;
}
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.ToDictionary(keySelector, null);
}
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
return source.ToDictionary(keySelector, Function<TSource>.Identity, comparer);
}
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
Check.Source(source);
return new List<TSource>(source);
}
public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return source.ToLookup(keySelector, Function<TSource>.Identity, null);
}
public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
return source.ToLookup(keySelector, Function<TSource>.Identity, comparer);
}
public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
{
return source.ToLookup(keySelector, elementSelector, null);
}
public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{
Check.SourceAndKeyElementSelectors(source, keySelector, elementSelector);
List<TElement> list = null;
Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>>(comparer ?? EqualityComparer<TKey>.Default);
foreach (TSource item in source) {
TKey val = keySelector(item);
List<TElement> value;
if (val == null) {
if (list == null)
list = new List<TElement>();
value = list;
} else if (!dictionary.TryGetValue(val, out value)) {
value = new List<TElement>();
dictionary.Add(val, value);
}
value.Add(elementSelector(item));
}
return new Lookup<TKey, TElement>(dictionary, (IEnumerable<TElement>)list);
}
public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
return first.SequenceEqual(second, null);
}
public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
Check.FirstAndSecond(first, second);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
using (IEnumerator<TSource> enumerator = first.GetEnumerator())
using (IEnumerator<TSource> enumerator2 = second.GetEnumerator()) {
while (enumerator.MoveNext()) {
if (!enumerator2.MoveNext())
return false;
if (!comparer.Equals(enumerator.Current, enumerator2.Current))
return false;
}
return !enumerator2.MoveNext();
}
}
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
Check.FirstAndSecond(first, second);
return first.Union(second, null);
}
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
Check.FirstAndSecond(first, second);
if (comparer == null)
comparer = EqualityComparer<TSource>.Default;
return CreateUnionIterator(first, second, comparer);
}
private static IEnumerable<TSource> CreateUnionIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
HashSet<TSource> items = new HashSet<TSource>(comparer);
foreach (TSource item in first) {
if (!items.Contains(item)) {
items.Add(item);
yield return item;
}
}
foreach (TSource item2 in second) {
if (!items.Contains(item2)) {
items.Add(item2);
yield return item2;
}
}
}
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
TSource[] array = source as TSource[];
if (array != null)
return CreateWhereIterator(array, predicate);
return CreateWhereIterator(source, predicate);
}
private static IEnumerable<TSource> CreateWhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource item in source) {
if (predicate(item))
yield return item;
}
}
private static IEnumerable<TSource> CreateWhereIterator<TSource>(TSource[] source, Func<TSource, bool> predicate)
{
int num;
for (int i = 0; i < source.Length; i = num) {
TSource val = source[i];
if (predicate(val))
yield return val;
num = i + 1;
}
}
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
Check.SourceAndPredicate(source, predicate);
TSource[] array = source as TSource[];
if (array != null)
return CreateWhereIterator(array, predicate);
return CreateWhereIterator(source, predicate);
}
private static IEnumerable<TSource> CreateWhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
int counter = 0;
foreach (TSource item in source) {
if (predicate(item, counter))
yield return item;
counter++;
}
}
private static IEnumerable<TSource> CreateWhereIterator<TSource>(TSource[] source, Func<TSource, int, bool> predicate)
{
int num;
for (int i = 0; i < source.Length; i = num) {
TSource val = source[i];
if (predicate(val, i))
yield return val;
num = i + 1;
}
}
internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
return ReadOnlyCollectionOf<TSource>.Empty;
ReadOnlyCollection<TSource> readOnlyCollection = source as ReadOnlyCollection<TSource>;
if (readOnlyCollection != null)
return readOnlyCollection;
return new ReadOnlyCollection<TSource>((IList<TSource>)source.ToArray());
}
private static Exception EmptySequence()
{
return new InvalidOperationException("Sequence contains no elements");
}
private static Exception NoMatchingElement()
{
return new InvalidOperationException("Sequence contains no matching element");
}
private static Exception MoreThanOneElement()
{
return new InvalidOperationException("Sequence contains more than one element");
}
private static Exception MoreThanOneMatchingElement()
{
return new InvalidOperationException("Sequence contains more than one matching element");
}
}
}