diff --git a/MoreLinq.Test/RankTest.cs b/MoreLinq.Test/RankTest.cs index ad36c7afb..6e84dc719 100644 --- a/MoreLinq.Test/RankTest.cs +++ b/MoreLinq.Test/RankTest.cs @@ -124,7 +124,7 @@ public void TestRankGroupedItems() .Concat(Enumerable.Range(0, count)) .Concat(Enumerable.Range(0, count)); using var ts = sequence.AsTestingSequence(); - var result = ts.Rank(); + var result = ts.Rank().ToArray(); Assert.That(result.Distinct().Count(), Is.EqualTo(count)); Assert.That(result, Is.EqualTo(sequence.Reverse().Select(x => x + 1))); diff --git a/MoreLinq/Assert.cs b/MoreLinq/Assert.cs index 1b272d8ed..0836113a6 100644 --- a/MoreLinq/Assert.cs +++ b/MoreLinq/Assert.cs @@ -65,7 +65,9 @@ public static IEnumerable Assert(this IEnumerable sou if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); - return _(); IEnumerable _() + return _(source, predicate, errorSelector); + + static IEnumerable _(IEnumerable source, Func predicate, Func? errorSelector) { foreach (var element in source) { diff --git a/MoreLinq/AssertCount.cs b/MoreLinq/AssertCount.cs index 14a55c1a4..f742f36c7 100644 --- a/MoreLinq/AssertCount.cs +++ b/MoreLinq/AssertCount.cs @@ -70,7 +70,9 @@ public static IEnumerable AssertCount(this IEnumerable _() + return _(source, count, errorSelector); + + static IEnumerable _(IEnumerable source, int count, Func errorSelector) { if (source.TryAsCollectionLike() is { Count: var collectionCount } && collectionCount.CompareTo(count) is var comparison && comparison != 0) diff --git a/MoreLinq/Backsert.cs b/MoreLinq/Backsert.cs index 490e7702e..47407bf83 100644 --- a/MoreLinq/Backsert.cs +++ b/MoreLinq/Backsert.cs @@ -65,10 +65,10 @@ public static IEnumerable Backsert(this IEnumerable first, IEnumerable< { < 0 => throw new ArgumentOutOfRangeException(nameof(index), "Index cannot be negative."), 0 => first.Concat(second), - _ => _() + _ => _(first, second, index) }; - IEnumerable _() + static IEnumerable _(IEnumerable first, IEnumerable second, int index) { using var e = first.CountDown(index, ValueTuple.Create).GetEnumerator(); diff --git a/MoreLinq/Batch.cs b/MoreLinq/Batch.cs index 5da60c07a..3d30e4f1f 100644 --- a/MoreLinq/Batch.cs +++ b/MoreLinq/Batch.cs @@ -86,7 +86,9 @@ public static IEnumerable Batch(this IEnumerable _() + return _(source, size, resultSelector); + + static IEnumerable _(IEnumerable source, int size, Func resultSelector) { switch (source) { diff --git a/MoreLinq/Cartesian.g.cs b/MoreLinq/Cartesian.g.cs index 64694c065..74740706c 100644 --- a/MoreLinq/Cartesian.g.cs +++ b/MoreLinq/Cartesian.g.cs @@ -69,7 +69,12 @@ public static IEnumerable Cartesian( if (second == null) throw new ArgumentNullException(nameof(second)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(first, second, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + Func resultSelector) { IEnumerable secondMemo; @@ -123,7 +128,13 @@ public static IEnumerable Cartesian( if (third == null) throw new ArgumentNullException(nameof(third)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(first, second, third, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; @@ -185,7 +196,14 @@ public static IEnumerable Cartesian( if (fourth == null) throw new ArgumentNullException(nameof(fourth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(first, second, third, fourth, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; @@ -255,7 +273,15 @@ public static IEnumerable Cartesian( if (fifth == null) throw new ArgumentNullException(nameof(fifth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(first, second, third, fourth, fifth, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; @@ -333,7 +359,16 @@ public static IEnumerable Cartesian( if (sixth == null) throw new ArgumentNullException(nameof(sixth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(first, second, third, fourth, fifth, sixth, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; @@ -419,7 +454,17 @@ public static IEnumerable Cartesian _() + return _(first, second, third, fourth, fifth, sixth, seventh, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; @@ -513,7 +558,18 @@ public static IEnumerable Cartesian _() + return _(first, second, third, fourth, fifth, sixth, seventh, eighth, resultSelector); + + static IEnumerable _( + IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, + Func resultSelector) { IEnumerable secondMemo; IEnumerable thirdMemo; diff --git a/MoreLinq/Cartesian.g.tt b/MoreLinq/Cartesian.g.tt index 4bc112cea..4c078b9bc 100644 --- a/MoreLinq/Cartesian.g.tt +++ b/MoreLinq/Cartesian.g.tt @@ -115,7 +115,14 @@ Func<<#= string.Join(", ", from x in o.Arguments select "T" + x.Number) #>, TRes <# } #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(<#= string.Join(", ", from x in o.Arguments select x.Ordinal) #>, resultSelector); + + static IEnumerable _( + <# foreach (var arg in o.Arguments) { #> +IEnumerable> <#= arg.Ordinal #>, + <# + } #> +Func<<#= string.Join(", ", from x in o.Arguments select "T" + x.Number) #>, TResult> resultSelector) { <# foreach (var arg in o.Arguments.Skip(1)) { #> IEnumerable> <#= arg.Ordinal #>Memo; diff --git a/MoreLinq/Choose.cs b/MoreLinq/Choose.cs index bffbc72d9..865fb3928 100644 --- a/MoreLinq/Choose.cs +++ b/MoreLinq/Choose.cs @@ -55,7 +55,11 @@ public static IEnumerable Choose(this IEnumerable source if (source == null) throw new ArgumentNullException(nameof(source)); if (chooser == null) throw new ArgumentNullException(nameof(chooser)); - return _(); IEnumerable _() + return _(source, chooser); + + static IEnumerable _( + IEnumerable source, + Func chooser) { foreach (var item in source) { diff --git a/MoreLinq/CountBy.cs b/MoreLinq/CountBy.cs index c1f8873ed..0ea540d81 100644 --- a/MoreLinq/CountBy.cs +++ b/MoreLinq/CountBy.cs @@ -55,7 +55,9 @@ public static IEnumerable> CountBy(this I if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - return _(); IEnumerable> _() + return _(source, keySelector, comparer); + + static IEnumerable> _(IEnumerable source, Func keySelector, IEqualityComparer? comparer) { List keys; List counts; diff --git a/MoreLinq/CountDown.cs b/MoreLinq/CountDown.cs index 53310e79a..aa0da23ce 100644 --- a/MoreLinq/CountDown.cs +++ b/MoreLinq/CountDown.cs @@ -58,12 +58,15 @@ public static IEnumerable CountDown(this IEnumerable sou if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return source.TryAsListLike() is { } listLike - ? IterateList(listLike) + ? IterateList(listLike, count, resultSelector) : source.TryAsCollectionLike() is { } collectionLike - ? IterateCollection(collectionLike) - : IterateSequence(); + ? IterateCollection(collectionLike, count, resultSelector) + : IterateSequence(source, count, resultSelector); - IEnumerable IterateList(ListLike list) + static IEnumerable IterateList( + ListLike list, + int count, + Func resultSelector) { var listCount = list.Count; var countdown = Math.Min(count, listCount); @@ -72,14 +75,20 @@ IEnumerable IterateList(ListLike list) yield return resultSelector(list[i], listCount - i <= count ? --countdown : null); } - IEnumerable IterateCollection(CollectionLike collection) + static IEnumerable IterateCollection( + CollectionLike collection, + int count, + Func resultSelector) { var i = collection.Count; foreach (var item in collection) yield return resultSelector(item, i-- <= count ? i : null); } - IEnumerable IterateSequence() + static IEnumerable IterateSequence( + IEnumerable source, + int count, + Func resultSelector) { var queue = new Queue(Math.Max(1, count + 1)); diff --git a/MoreLinq/DistinctBy.cs b/MoreLinq/DistinctBy.cs index 1079ff814..834e60f70 100644 --- a/MoreLinq/DistinctBy.cs +++ b/MoreLinq/DistinctBy.cs @@ -78,7 +78,12 @@ public static IEnumerable DistinctBy(this IEnumerable _() + return _(source, keySelector, comparer); + + static IEnumerable _( + IEnumerable source, + Func keySelector, + IEqualityComparer? comparer) { var knownKeys = new HashSet(comparer); foreach (var element in source) diff --git a/MoreLinq/EndsWith.cs b/MoreLinq/EndsWith.cs index d414a3dc0..99ce9428f 100644 --- a/MoreLinq/EndsWith.cs +++ b/MoreLinq/EndsWith.cs @@ -78,14 +78,14 @@ public static bool EndsWith(this IEnumerable first, IEnumerable second, return second.TryAsCollectionLike() is { Count: var secondCount } ? first.TryAsCollectionLike() is { Count: var firstCount } && secondCount > firstCount ? false - : Impl(second, secondCount) - : Impl(secondList = second.ToList(), secondList.Count); + : Impl(first, second, secondCount, comparer) + : Impl(first, secondList = second.ToList(), secondList.Count, comparer); #pragma warning restore IDE0075 // Simplify conditional expression - bool Impl(IEnumerable snd, int count) + static bool Impl(IEnumerable first, IEnumerable second, int count, IEqualityComparer comparer) { using var firstIter = first.TakeLast(count).GetEnumerator(); - return snd.All(item => firstIter.MoveNext() && comparer.Equals(firstIter.Current, item)); + return second.All(item => firstIter.MoveNext() && comparer.Equals(firstIter.Current, item)); } } } diff --git a/MoreLinq/ExceptBy.cs b/MoreLinq/ExceptBy.cs index 6a5e1f2c6..2a8fe7911 100644 --- a/MoreLinq/ExceptBy.cs +++ b/MoreLinq/ExceptBy.cs @@ -79,9 +79,13 @@ public static IEnumerable ExceptBy(this IEnumerable Impl() + static IEnumerable Impl( + IEnumerable first, + IEnumerable second, + Func keySelector, + IEqualityComparer? keyComparer) { // TODO Use ToHashSet var keys = new HashSet(second.Select(keySelector), keyComparer); diff --git a/MoreLinq/Exclude.cs b/MoreLinq/Exclude.cs index 455861862..6d416d0fa 100644 --- a/MoreLinq/Exclude.cs +++ b/MoreLinq/Exclude.cs @@ -41,10 +41,10 @@ public static IEnumerable Exclude(this IEnumerable sequence, int startI { < 0 => throw new ArgumentOutOfRangeException(nameof(count)), 0 => sequence, - _ => _() + _ => _(sequence, startIndex, count) }; - IEnumerable _() + static IEnumerable _(IEnumerable sequence, int startIndex, int count) { var index = 0; var endIndex = startIndex + count; diff --git a/MoreLinq/Experimental/Async/Merge.cs b/MoreLinq/Experimental/Async/Merge.cs index f414eaa7d..03ae97c82 100644 --- a/MoreLinq/Experimental/Async/Merge.cs +++ b/MoreLinq/Experimental/Async/Merge.cs @@ -85,9 +85,9 @@ public static IAsyncEnumerable Merge(this IEnumerable> if (sources is null) throw new ArgumentNullException(nameof(sources)); if (maxConcurrent <= 0) throw new ArgumentOutOfRangeException(nameof(maxConcurrent)); - return Async(); + return Async(sources, maxConcurrent); - async IAsyncEnumerable Async([EnumeratorCancellation]CancellationToken cancellationToken = default) + static async IAsyncEnumerable Async(IEnumerable> sources, int maxConcurrent, [EnumeratorCancellation]CancellationToken cancellationToken = default) { using var thisCancellationTokenSource = new CancellationTokenSource(); diff --git a/MoreLinq/Experimental/Await.cs b/MoreLinq/Experimental/Await.cs index 717a209bc..dca801b51 100644 --- a/MoreLinq/Experimental/Await.cs +++ b/MoreLinq/Experimental/Await.cs @@ -424,11 +424,20 @@ public static IAwaitQuery AwaitCompletion( return AwaitQuery.Create( - options => Impl(options.MaxConcurrency, + options => Impl(source, + evaluator, + resultSelector, + options.MaxConcurrency, options.Scheduler ?? TaskScheduler.Default, options.PreserveOrder)); - IEnumerable Impl(int? maxConcurrency, TaskScheduler scheduler, bool ordered) + static IEnumerable Impl( + IEnumerable source, + Func> evaluator, + Func, TResult> resultSelector, + int? maxConcurrency, + TaskScheduler scheduler, + bool ordered) { // A separate task will enumerate the source and launch tasks. // It will post all progress as notices to the collection below. diff --git a/MoreLinq/Experimental/Batch.cs b/MoreLinq/Experimental/Batch.cs index 9e9c28425..d3c444804 100644 --- a/MoreLinq/Experimental/Batch.cs +++ b/MoreLinq/Experimental/Batch.cs @@ -145,7 +145,12 @@ public static IEnumerable if (bucketProjectionSelector == null) throw new ArgumentNullException(nameof(bucketProjectionSelector)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(source, size, pool, bucketProjectionSelector, resultSelector); + + static IEnumerable _( + IEnumerable source, int size, ArrayPool pool, + Func, IEnumerable> bucketProjectionSelector, + Func, TResult> resultSelector) { using var batch = source.Batch(size, pool); var bucket = bucketProjectionSelector(batch.CurrentBuffer); diff --git a/MoreLinq/FallbackIfEmpty.cs b/MoreLinq/FallbackIfEmpty.cs index 159a7de4f..a54db158c 100644 --- a/MoreLinq/FallbackIfEmpty.cs +++ b/MoreLinq/FallbackIfEmpty.cs @@ -161,7 +161,16 @@ static IEnumerable FallbackIfEmptyImpl(IEnumerable source, int? count, T? fallback1, T? fallback2, T? fallback3, T? fallback4, IEnumerable? fallback) { - return _(); IEnumerable _() + return _(source, count, fallback1, fallback2, fallback3, fallback4, fallback); + + static IEnumerable _( + IEnumerable source, + int? count, + T? fallback1, + T? fallback2, + T? fallback3, + T? fallback4, + IEnumerable? fallback) { if (source.TryAsCollectionLike() is null or { Count: > 0 }) { diff --git a/MoreLinq/Flatten.cs b/MoreLinq/Flatten.cs index eaee331d2..b2f5eb739 100644 --- a/MoreLinq/Flatten.cs +++ b/MoreLinq/Flatten.cs @@ -118,14 +118,20 @@ public static IEnumerable< if (source == null) throw new ArgumentNullException(nameof(source)); if (selector == null) throw new ArgumentNullException(nameof(selector)); - return _(); + return _(source, selector); - IEnumerable< + static IEnumerable< // Just like "IEnumerable.Current" is null-oblivious, so is this: #nullable disable -/*...................*/ object +/*..........................*/ object #nullable restore -/*.........................*/ > _() +/*.................................*/ > _(IEnumerable source, + Func< +// Just like "IEnumerable.Current" is null-oblivious, so is this: +#nullable disable +/*..........................................*/ object, +#nullable restore +/*..................................................*/ IEnumerable?> selector) { var e = source.GetEnumerator(); var stack = new Stack(); diff --git a/MoreLinq/From.cs b/MoreLinq/From.cs index b9bf76faa..bf2e826d6 100644 --- a/MoreLinq/From.cs +++ b/MoreLinq/From.cs @@ -36,7 +36,9 @@ partial class MoreEnumerable public static IEnumerable From(Func function) { - return _(); IEnumerable _() + return _(function); + + static IEnumerable _(Func function) { #pragma warning disable CA1062 // Validate arguments of public methods yield return function(); @@ -59,7 +61,9 @@ public static IEnumerable From(Func function) public static IEnumerable From(Func function1, Func function2) { - return _(); IEnumerable _() + return _(function1, function2); + + static IEnumerable _(Func function1, Func function2) { #pragma warning disable CA1062 // Validate arguments of public methods yield return function1(); @@ -84,7 +88,9 @@ public static IEnumerable From(Func function1, Func function2) public static IEnumerable From(Func function1, Func function2, Func function3) { - return _(); IEnumerable _() + return _(function1, function2, function3); + + static IEnumerable _(Func function1, Func function2, Func function3) { #pragma warning disable CA1062 // Validate arguments of public methods yield return function1(); diff --git a/MoreLinq/FullGroupJoin.cs b/MoreLinq/FullGroupJoin.cs index 2f6fb56c8..455940cc0 100644 --- a/MoreLinq/FullGroupJoin.cs +++ b/MoreLinq/FullGroupJoin.cs @@ -146,9 +146,15 @@ public static IEnumerable FullGroupJoin if (secondKeySelector == null) throw new ArgumentNullException(nameof(secondKeySelector)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(comparer ?? EqualityComparer.Default); + return _(first, second, firstKeySelector, secondKeySelector, resultSelector, comparer ?? EqualityComparer.Default); - IEnumerable _(IEqualityComparer comparer) + static IEnumerable _( + IEnumerable first, + IEnumerable second, + Func firstKeySelector, + Func secondKeySelector, + Func, IEnumerable, TResult> resultSelector, + IEqualityComparer comparer) { var alookup = Lookup.CreateForJoin(first, firstKeySelector, comparer); var blookup = Lookup.CreateForJoin(second, secondKeySelector, comparer); diff --git a/MoreLinq/FullJoin.cs b/MoreLinq/FullJoin.cs index 9b2da6d12..6d59386e7 100644 --- a/MoreLinq/FullJoin.cs +++ b/MoreLinq/FullJoin.cs @@ -228,9 +228,17 @@ public static IEnumerable FullJoin( if (secondSelector == null) throw new ArgumentNullException(nameof(secondSelector)); if (bothSelector == null) throw new ArgumentNullException(nameof(bothSelector)); - return Impl(); + return Impl(first, second, firstKeySelector, secondKeySelector, firstSelector, secondSelector, bothSelector, comparer); - IEnumerable Impl() + static IEnumerable Impl( + IEnumerable first, + IEnumerable second, + Func firstKeySelector, + Func secondKeySelector, + Func firstSelector, + Func secondSelector, + Func bothSelector, + IEqualityComparer? comparer) { var seconds = second.Select(e => new KeyValuePair(secondKeySelector(e), e)).ToArray(); var secondLookup = seconds.ToLookup(e => e.Key, e => e.Value, comparer); diff --git a/MoreLinq/Generate.cs b/MoreLinq/Generate.cs index a15b38486..519e9785f 100644 --- a/MoreLinq/Generate.cs +++ b/MoreLinq/Generate.cs @@ -45,7 +45,9 @@ public static IEnumerable Generate(TResult initial, Func _() + return _(initial, generator); + + static IEnumerable _(TResult initial, Func generator) { var current = initial; while (true) diff --git a/MoreLinq/Insert.cs b/MoreLinq/Insert.cs index 11c337ba3..774a7df9f 100644 --- a/MoreLinq/Insert.cs +++ b/MoreLinq/Insert.cs @@ -55,7 +55,9 @@ public static IEnumerable Insert(this IEnumerable first, IEnumerable if (second == null) throw new ArgumentNullException(nameof(second)); if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), "Index cannot be negative."); - return _(); IEnumerable _() + return _(first, second, index); + + static IEnumerable _(IEnumerable first, IEnumerable second, int index) { var i = -1; diff --git a/MoreLinq/Lag.cs b/MoreLinq/Lag.cs index 4b532a649..f3ac4cacb 100644 --- a/MoreLinq/Lag.cs +++ b/MoreLinq/Lag.cs @@ -83,7 +83,13 @@ public static IEnumerable Lag(this IEnumerable _() + return _(source, offset, defaultLagValue, resultSelector); + + static IEnumerable _( + IEnumerable source, + int offset, + TSource defaultLagValue, + Func resultSelector) { using var iter = source.GetEnumerator(); diff --git a/MoreLinq/Lead.cs b/MoreLinq/Lead.cs index 2a0b7cbb3..392e55b99 100644 --- a/MoreLinq/Lead.cs +++ b/MoreLinq/Lead.cs @@ -80,7 +80,13 @@ public static IEnumerable Lead(this IEnumerable _() + return _(source, offset, defaultLeadValue, resultSelector); + + static IEnumerable _( + IEnumerable source, + int offset, + TSource defaultLeadValue, + Func resultSelector) { var leadQueue = new Queue(offset); using var iter = source.GetEnumerator(); diff --git a/MoreLinq/Maxima.cs b/MoreLinq/Maxima.cs index 645ea374d..9f4a35c1a 100644 --- a/MoreLinq/Maxima.cs +++ b/MoreLinq/Maxima.cs @@ -312,10 +312,13 @@ static IEnumerable ExtremaBy( Extrema extrema, int? limit, Func selector, Func comparer) { - foreach (var item in Extrema()) + foreach (var item in Extrema(source, extrema, limit, selector, comparer)) yield return item; - IEnumerable Extrema() + static IEnumerable Extrema( + IEnumerable source, + Extrema extrema, int? limit, + Func selector, Func comparer) { using var e = source.GetEnumerator(); diff --git a/MoreLinq/Move.cs b/MoreLinq/Move.cs index 43e38d2d7..73dbfc849 100644 --- a/MoreLinq/Move.cs +++ b/MoreLinq/Move.cs @@ -58,10 +58,10 @@ public static IEnumerable Move(this IEnumerable source, int fromIndex, return source; return toIndex < fromIndex - ? _(toIndex, fromIndex - toIndex, count) - : _(fromIndex, count, toIndex - fromIndex); + ? _(source, toIndex, fromIndex - toIndex, count) + : _(source, fromIndex, count, toIndex - fromIndex); - IEnumerable _(int bufferStartIndex, int bufferSize, int bufferYieldIndex) + static IEnumerable _(IEnumerable source, int bufferStartIndex, int bufferSize, int bufferYieldIndex) { var hasMore = true; bool MoveNext(IEnumerator e) => hasMore && (hasMore = e.MoveNext()); diff --git a/MoreLinq/OrderedMerge.cs b/MoreLinq/OrderedMerge.cs index 0e30e1517..3f4a7e5e8 100644 --- a/MoreLinq/OrderedMerge.cs +++ b/MoreLinq/OrderedMerge.cs @@ -282,9 +282,24 @@ public static IEnumerable OrderedMerge( if (bothSelector == null) throw new ArgumentNullException(nameof(bothSelector)); if (secondSelector == null) throw new ArgumentNullException(nameof(secondSelector)); - return _(comparer ?? Comparer.Default); + return _(first, + second, + firstKeySelector, + secondKeySelector, + firstSelector, + secondSelector, + bothSelector, + comparer ?? Comparer.Default); - IEnumerable _(IComparer comparer) + static IEnumerable _( + IEnumerable first, + IEnumerable second, + Func firstKeySelector, + Func secondKeySelector, + Func firstSelector, + Func secondSelector, + Func bothSelector, + IComparer comparer) { using var e1 = first.GetEnumerator(); using var e2 = second.GetEnumerator(); diff --git a/MoreLinq/PadStart.cs b/MoreLinq/PadStart.cs index 5e9e380d1..639e15305 100644 --- a/MoreLinq/PadStart.cs +++ b/MoreLinq/PadStart.cs @@ -117,7 +117,13 @@ public static IEnumerable PadStart(this IEnumerable s static IEnumerable PadStartImpl(IEnumerable source, int width, T? padding, Func? paddingSelector) { - return _(); IEnumerable _() + return _(source, width, padding, paddingSelector); + + static IEnumerable _( + IEnumerable source, + int width, + T? padding, + Func? paddingSelector) { if (source.TryAsCollectionLike() is { Count: var collectionCount } && collectionCount < width) { diff --git a/MoreLinq/Pairwise.cs b/MoreLinq/Pairwise.cs index 9e262e85d..6b9c4347d 100644 --- a/MoreLinq/Pairwise.cs +++ b/MoreLinq/Pairwise.cs @@ -53,7 +53,9 @@ public static IEnumerable Pairwise(this IEnumerable _() + return _(source, resultSelector); + + static IEnumerable _(IEnumerable source, Func resultSelector) { using var e = source.GetEnumerator(); diff --git a/MoreLinq/Permutations.cs b/MoreLinq/Permutations.cs index 2324750bb..dd60235a4 100644 --- a/MoreLinq/Permutations.cs +++ b/MoreLinq/Permutations.cs @@ -49,7 +49,9 @@ public static IEnumerable> Permutations(this IEnumerable sequence { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); - return _(); IEnumerable> _() + return _(sequence); + + static IEnumerable> _(IEnumerable sequence) { // The algorithm used to generate permutations uses the fact that any set can be put // into 1-to-1 correspondence with the set of ordinals number (0..n). The diff --git a/MoreLinq/Pipe.cs b/MoreLinq/Pipe.cs index 474ef725e..94c5c6138 100644 --- a/MoreLinq/Pipe.cs +++ b/MoreLinq/Pipe.cs @@ -43,7 +43,9 @@ public static IEnumerable Pipe(this IEnumerable source, Action actio if (source == null) throw new ArgumentNullException(nameof(source)); if (action == null) throw new ArgumentNullException(nameof(action)); - return _(); IEnumerable _() + return _(source, action); + + static IEnumerable _(IEnumerable source, Action action) { foreach (var element in source) { diff --git a/MoreLinq/PreScan.cs b/MoreLinq/PreScan.cs index 88aa8f57c..a23763722 100644 --- a/MoreLinq/PreScan.cs +++ b/MoreLinq/PreScan.cs @@ -59,7 +59,12 @@ public static IEnumerable PreScan( if (source == null) throw new ArgumentNullException(nameof(source)); if (transformation == null) throw new ArgumentNullException(nameof(transformation)); - return _(); IEnumerable _() + return _(source, transformation, identity); + + static IEnumerable _( + IEnumerable source, + Func transformation, + TSource identity) { var aggregator = identity; using var e = source.GetEnumerator(); diff --git a/MoreLinq/Rank.cs b/MoreLinq/Rank.cs index 4e5586382..4232fac00 100644 --- a/MoreLinq/Rank.cs +++ b/MoreLinq/Rank.cs @@ -77,9 +77,9 @@ public static IEnumerable RankBy(this IEnumerable s if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); - return _(comparer ?? Comparer.Default); + return _(source, keySelector, comparer ?? Comparer.Default); - IEnumerable _(IComparer comparer) + static IEnumerable _(IEnumerable source, Func keySelector, IComparer comparer) { source = source.ToArray(); // avoid enumerating source twice diff --git a/MoreLinq/RunLengthEncode.cs b/MoreLinq/RunLengthEncode.cs index 232c38e37..f701de31f 100644 --- a/MoreLinq/RunLengthEncode.cs +++ b/MoreLinq/RunLengthEncode.cs @@ -49,9 +49,9 @@ public static IEnumerable> RunLengthEncode(this IEnumera { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); - return _(comparer ?? EqualityComparer.Default); + return _(sequence, comparer ?? EqualityComparer.Default); - IEnumerable> _(IEqualityComparer comparer) + static IEnumerable> _(IEnumerable sequence, IEqualityComparer comparer) { // This implementation could also have been written using a foreach loop, // but it proved to be easier to deal with edge certain cases that occur diff --git a/MoreLinq/ScanBy.cs b/MoreLinq/ScanBy.cs index 3ca138ced..d12d1de7f 100644 --- a/MoreLinq/ScanBy.cs +++ b/MoreLinq/ScanBy.cs @@ -85,9 +85,14 @@ public static IEnumerable> ScanBy.Default); + return _(source, keySelector, seedSelector, accumulator, comparer ?? EqualityComparer.Default); - IEnumerable> _(IEqualityComparer comparer) + static IEnumerable> _( + IEnumerable source, + Func keySelector, + Func seedSelector, + Func accumulator, + IEqualityComparer comparer) { var stateByKey = new Collections.Dictionary(comparer); diff --git a/MoreLinq/Segment.cs b/MoreLinq/Segment.cs index 859f59014..e29ecdce0 100644 --- a/MoreLinq/Segment.cs +++ b/MoreLinq/Segment.cs @@ -74,7 +74,9 @@ public static IEnumerable> Segment(this IEnumerable source, if (source == null) throw new ArgumentNullException(nameof(source)); if (newSegmentPredicate == null) throw new ArgumentNullException(nameof(newSegmentPredicate)); - return _(); IEnumerable> _() + return _(source, newSegmentPredicate); + + static IEnumerable> _(IEnumerable source, Func newSegmentPredicate) { using var e = source.GetEnumerator(); diff --git a/MoreLinq/SkipUntil.cs b/MoreLinq/SkipUntil.cs index 7a738c35c..07a45f667 100644 --- a/MoreLinq/SkipUntil.cs +++ b/MoreLinq/SkipUntil.cs @@ -57,7 +57,9 @@ public static IEnumerable SkipUntil(this IEnumerable if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); - return _(); IEnumerable _() + return _(source, predicate); + + static IEnumerable _(IEnumerable source, Func predicate) { using var enumerator = source.GetEnumerator(); diff --git a/MoreLinq/Slice.cs b/MoreLinq/Slice.cs index 86f8306fa..5867d58fa 100644 --- a/MoreLinq/Slice.cs +++ b/MoreLinq/Slice.cs @@ -55,12 +55,12 @@ public static IEnumerable Slice(this IEnumerable sequence, int startInd return sequence switch { - IList list => SliceList(list.Count, i => list[i]), - IReadOnlyList list => SliceList(list.Count, i => list[i]), + IList list => SliceList(startIndex, count, list.Count, i => list[i]), + IReadOnlyList list => SliceList(startIndex, count, list.Count, i => list[i]), var seq => seq.Skip(startIndex).Take(count) }; - IEnumerable SliceList(int listCount, Func indexer) + static IEnumerable SliceList(int startIndex, int count, int listCount, Func indexer) { var countdown = count; var index = startIndex; diff --git a/MoreLinq/SortedMerge.cs b/MoreLinq/SortedMerge.cs index 03757dcb5..04d328099 100644 --- a/MoreLinq/SortedMerge.cs +++ b/MoreLinq/SortedMerge.cs @@ -96,7 +96,7 @@ public static IEnumerable SortedMerge(this IEnumerable comparer.Compare(b, a) > 0; // return the sorted merge result - return Impl(new[] { source }.Concat(otherSequences)); + return Impl(new[] { source }.Concat(otherSequences), precedenceFunc); // Private implementation method that performs a merge of multiple, ordered sequences using // a precedence function which encodes order-sensitive comparison logic based on the caller's arguments. @@ -109,7 +109,7 @@ public static IEnumerable SortedMerge(this IEnumerableN => otherSequences.Count()+1. - IEnumerable Impl(IEnumerable> sequences) + static IEnumerable Impl(IEnumerable> sequences, Func precedenceFunc) { using var disposables = new DisposableGroup(sequences.Select(e => e.GetEnumerator()).Acquire()); diff --git a/MoreLinq/Split.cs b/MoreLinq/Split.cs index 935537aa5..5edb1f0ba 100644 --- a/MoreLinq/Split.cs +++ b/MoreLinq/Split.cs @@ -267,7 +267,13 @@ public static IEnumerable Split(this IEnumerable _() + return _(source, separatorFunc, count, resultSelector); + + static IEnumerable _( + IEnumerable source, + Func separatorFunc, + int count, + Func, TResult> resultSelector) { if (count == 0) // No splits? { diff --git a/MoreLinq/Subsets.cs b/MoreLinq/Subsets.cs index f1167152f..9ffe27f05 100644 --- a/MoreLinq/Subsets.cs +++ b/MoreLinq/Subsets.cs @@ -51,7 +51,9 @@ public static IEnumerable> Subsets(this IEnumerable sequence) { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); - return _(); IEnumerable> _() + return _(sequence); + + static IEnumerable> _(IEnumerable sequence) { var sequenceAsList = sequence.ToList(); var sequenceLength = sequenceAsList.Count; @@ -113,7 +115,9 @@ public static IEnumerable> Subsets(this IEnumerable sequence, int // preconditions. This however, needs to be carefully considered - and perhaps // may change after further thought and review. - return _(); IEnumerable> _() + return _(sequence, subsetSize); + + static IEnumerable> _(IEnumerable sequence, int subsetSize) { foreach (var subset in Subsets(sequence.ToList(), subsetSize)) yield return subset; diff --git a/MoreLinq/TagFirstLast.cs b/MoreLinq/TagFirstLast.cs index 61d90f6e7..705b22a04 100644 --- a/MoreLinq/TagFirstLast.cs +++ b/MoreLinq/TagFirstLast.cs @@ -59,7 +59,9 @@ public static IEnumerable TagFirstLast(this IEnumerab if (source == null) throw new ArgumentNullException(nameof(source)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(); IEnumerable _() + return _(source, resultSelector); + + static IEnumerable _(IEnumerable source, Func resultSelector) { using var enumerator = source.GetEnumerator(); diff --git a/MoreLinq/TakeUntil.cs b/MoreLinq/TakeUntil.cs index bceb05c22..3488a3bec 100644 --- a/MoreLinq/TakeUntil.cs +++ b/MoreLinq/TakeUntil.cs @@ -57,7 +57,9 @@ public static IEnumerable TakeUntil(this IEnumerable if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); - return _(); IEnumerable _() + return _(source, predicate); + + static IEnumerable _(IEnumerable source, Func predicate) { foreach (var item in source) { diff --git a/MoreLinq/Transpose.cs b/MoreLinq/Transpose.cs index eb1a151bd..e6841a9ca 100644 --- a/MoreLinq/Transpose.cs +++ b/MoreLinq/Transpose.cs @@ -56,7 +56,9 @@ public static IEnumerable> Transpose(this IEnumerable> _() + return _(source); + + static IEnumerable> _(IEnumerable> source) { #pragma warning disable IDE0007 // Use implicit type (false positive) IEnumerator?[] enumerators = source.Select(e => e.GetEnumerator()).Acquire(); diff --git a/MoreLinq/Traverse.cs b/MoreLinq/Traverse.cs index 4fb46b5b8..1ec5b0d9b 100644 --- a/MoreLinq/Traverse.cs +++ b/MoreLinq/Traverse.cs @@ -48,7 +48,9 @@ public static IEnumerable TraverseBreadthFirst(T root, Func _() + return _(root, childrenSelector); + + static IEnumerable _(T root, Func> childrenSelector) { var queue = new Queue(); queue.Enqueue(root); @@ -88,7 +90,9 @@ public static IEnumerable TraverseDepthFirst(T root, Func _() + return _(root, childrenSelector); + + static IEnumerable _(T root, Func> childrenSelector) { var stack = new Stack(); stack.Push(root); diff --git a/MoreLinq/Unfold.cs b/MoreLinq/Unfold.cs index d6f5b8738..380a10858 100644 --- a/MoreLinq/Unfold.cs +++ b/MoreLinq/Unfold.cs @@ -61,7 +61,14 @@ public static IEnumerable Unfold( if (stateSelector == null) throw new ArgumentNullException(nameof(stateSelector)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return _(state); IEnumerable _(TState initialState) + return _(state, generator, predicate, stateSelector, resultSelector); + + static IEnumerable _( + TState initialState, + Func generator, + Func predicate, + Func stateSelector, + Func resultSelector) { for (var state = initialState; ;) { diff --git a/MoreLinq/Window.cs b/MoreLinq/Window.cs index 04b1ddefd..e3de531f7 100644 --- a/MoreLinq/Window.cs +++ b/MoreLinq/Window.cs @@ -44,7 +44,9 @@ public static IEnumerable> Window(this IEnumerable> _() + return _(source, size); + + static IEnumerable> _(IEnumerable source, int size) { using var iter = source.GetEnumerator(); diff --git a/MoreLinq/WindowLeft.cs b/MoreLinq/WindowLeft.cs index fdcd72803..43dc0ad8a 100644 --- a/MoreLinq/WindowLeft.cs +++ b/MoreLinq/WindowLeft.cs @@ -63,7 +63,9 @@ public static IEnumerable> WindowLeft(this IEnumerable> _() + return _(source, size); + + static IEnumerable> _(IEnumerable source, int size) { var window = new List(); foreach (var item in source) diff --git a/MoreLinq/WindowRight.cs b/MoreLinq/WindowRight.cs index 4172c3d6d..52bd9a050 100644 --- a/MoreLinq/WindowRight.cs +++ b/MoreLinq/WindowRight.cs @@ -78,7 +78,11 @@ static IEnumerable> WindowRightWhile( if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); - return _(); IEnumerable> _() + return _(source, predicate); + + static IEnumerable> _( + IEnumerable source, + Func predicate) { var window = new List(); foreach (var item in source)