<PackageReference Include="NUnit" Version="3.10.1" />

Enumerable

public static class 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"); } } }