// Needed for NET40 #if !NET_4_6 using System; using System.Collections.Generic; namespace LinqInternal.Collections { internal static partial class Extensions { public static ICollection AsCollection(IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } if (source is string && typeof(T) == typeof(char)) { return (ICollection)(object)(source as string).ToCharArray(); } var result = source as ICollection; return result ?? new ProgressiveCollection(source); } public static ICollection AsDistinctCollection(IEnumerable source) { // Workaround for .NET 3.5 when all you want is Contains and no duplicates #if NET35 || !NET_4_6 if (source == null) { throw new ArgumentNullException("source"); } var resultHashSet = source as HashSet; if (resultHashSet == null) { var resultISet = source as ISet; if (resultISet == null) { return new ProgressiveSet(source); } return resultISet; } return resultHashSet; #else return AsSet(source); #endif } public static IList AsList(IEnumerable source) { var result = source as IList; if (result == null) { return new ProgressiveList(source); } return result; } public static ISet AsSet(IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } // Remember that On .NET 3.5 HashSet is not an ISet var resultISet = source as ISet; return resultISet ?? new ProgressiveSet(source); } public static IEnumerable AsUnaryEnumerable(this T source) { yield return source; } public static IList AsUnaryList(this T source) { return new ProgressiveList ( AsUnaryEnumerable(source) ); } public static ISet AsUnarySet(this T source) { return new ProgressiveSet ( AsUnaryEnumerable(source) ); } public static bool HasAtLeast(this IEnumerable source, int count) { if (source == null) { throw new ArgumentNullException("source"); } if (count == 0) { return true; } if (source is string && typeof(TSource) == typeof(char)) { return (source as string).Length >= count; } var sourceAsCollection = source as ICollection; if (sourceAsCollection != null) { return sourceAsCollection.Count >= count; } var result = 0; using (var item = source.GetEnumerator()) { while (item.MoveNext()) { checked { result++; } if (result == count) { return true; } } } return false; } public static IEnumerable SkipItems(this IEnumerable source, int skipCount) { if (source == null) { throw new ArgumentNullException("source"); } return SkipItemsExtracted(source, skipCount); } public static IEnumerable SkipItems(this IEnumerable source, Predicate predicateCount, int skipCount) { if (source == null) { throw new ArgumentNullException("source"); } return predicateCount == null ? SkipItemsExtracted(source, skipCount) : SkipItemsExtracted(source, predicateCount, skipCount); } public static IEnumerable StepItems(this IEnumerable source, int stepCount) { if (source == null) { throw new ArgumentNullException("source"); } return StepItemsExtracted(source, stepCount); } public static IEnumerable TakeItems(this IEnumerable source, int takeCount) { if (source == null) { throw new ArgumentNullException("source"); } return TakeItemsExtracted(source, takeCount); } public static IEnumerable TakeItems(this IEnumerable source, Predicate predicateCount, int takeCount) { if (source == null) { throw new ArgumentNullException("source"); } return predicateCount == null ? TakeItemsExtracted(source, takeCount) : TakeItemsExtracted(source, predicateCount, takeCount); } private static IEnumerable SkipItemsExtracted(IEnumerable source, int skipCount) { var count = 0; foreach (var item in source) { if (count < skipCount) { count++; } else { yield return item; } } } private static IEnumerable SkipItemsExtracted(IEnumerable source, Predicate predicateCount, int skipCount) { // NOTICE this method has no null check var count = 0; foreach (var item in source) { if (count < skipCount) { if (predicateCount(item)) { count++; } } else { yield return item; } } } private static IEnumerable StepItemsExtracted(this IEnumerable source, int stepCount) { var count = 0; foreach (var item in source) { if (count % stepCount == 0) { count++; } else { yield return item; count++; } } } private static IEnumerable TakeItemsExtracted(IEnumerable source, int takeCount) { var count = 0; foreach (var item in source) { if (count == takeCount) { break; } yield return item; count++; } } private static IEnumerable TakeItemsExtracted(IEnumerable source, Predicate predicateCount, int takeCount) { // NOTICE this method has no null check var count = 0; foreach (var item in source) { if (count == takeCount) { break; } yield return item; if (predicateCount(item)) { count++; } } } } } #endif