From dc6b373dbb8a1a4a1689e21c737c33792a3e2d8e Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Mon, 14 Nov 2022 12:52:24 +0100 Subject: [PATCH 1/3] Replace dammits (!) with debug assertions --- MoreLinq/Debug.cs | 31 ++++++++++++++ MoreLinq/Experimental/Await.cs | 4 +- MoreLinq/Experimental/Memoize.cs | 3 +- MoreLinq/FallbackIfEmpty.cs | 25 ++++++++--- MoreLinq/Fold.cs | 71 +++++++++++++++++++++++--------- MoreLinq/Lookup.cs | 30 +++++++++----- MoreLinq/Pad.cs | 1 - MoreLinq/PartialSort.cs | 3 +- MoreLinq/Partition.cs | 1 - MoreLinq/Reactive/Subject.cs | 4 +- 10 files changed, 130 insertions(+), 43 deletions(-) create mode 100644 MoreLinq/Debug.cs diff --git a/MoreLinq/Debug.cs b/MoreLinq/Debug.cs new file mode 100644 index 000000000..6b36c21c7 --- /dev/null +++ b/MoreLinq/Debug.cs @@ -0,0 +1,31 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2022 Atif Aziz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.Runtime.CompilerServices; + + static class Debug + { + [Conditional("DEBUG")] + public static void Assert([DoesNotReturnIf(false)] bool condition, + [CallerArgumentExpression(nameof(condition))] string? message = null) => + System.Diagnostics.Debug.Assert(condition); + } +} diff --git a/MoreLinq/Experimental/Await.cs b/MoreLinq/Experimental/Await.cs index 9b54d9e35..d4edbe18f 100644 --- a/MoreLinq/Experimental/Await.cs +++ b/MoreLinq/Experimental/Await.cs @@ -23,7 +23,6 @@ namespace MoreLinq.Experimental using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; - using System.Diagnostics; using System.Linq; using System.Runtime.ExceptionServices; using System.Threading; @@ -538,7 +537,8 @@ void PostNotice(Notice notice, if (kind == Notice.Error) { - error!.Throw(); + Debug.Assert(error is not null); + error.Throw(); } if (kind == Notice.End) diff --git a/MoreLinq/Experimental/Memoize.cs b/MoreLinq/Experimental/Memoize.cs index 0526cec4f..626564c45 100644 --- a/MoreLinq/Experimental/Memoize.cs +++ b/MoreLinq/Experimental/Memoize.cs @@ -116,7 +116,8 @@ public IEnumerator GetEnumerator() { if (index == _errorIndex) { - _error!.Throw(); + Debug.Assert(_error is not null); + _error.Throw(); } if (_sourceEnumerator == null) diff --git a/MoreLinq/FallbackIfEmpty.cs b/MoreLinq/FallbackIfEmpty.cs index 90256fcad..9c3aaab3d 100644 --- a/MoreLinq/FallbackIfEmpty.cs +++ b/MoreLinq/FallbackIfEmpty.cs @@ -19,7 +19,6 @@ namespace MoreLinq { using System; using System.Collections.Generic; - using System.Diagnostics; static partial class MoreEnumerable { @@ -190,10 +189,26 @@ IEnumerable FallbackOnArgs() { Debug.Assert(count is >= 1 and <= 4); - yield return fallback1!; - if (count > 1) yield return fallback2!; - if (count > 2) yield return fallback3!; - if (count > 3) yield return fallback4!; + Debug.Assert(fallback1 is not null); + yield return fallback1; + + if (count > 1) + { + Debug.Assert(fallback2 is not null); + yield return fallback2; + } + + if (count > 2) + { + Debug.Assert(fallback3 is not null); + yield return fallback3; + } + + if (count > 3) + { + Debug.Assert(fallback4 is not null); + yield return fallback4; + } } } } diff --git a/MoreLinq/Fold.cs b/MoreLinq/Fold.cs index 6698cec9a..c5ac37916 100644 --- a/MoreLinq/Fold.cs +++ b/MoreLinq/Fold.cs @@ -67,26 +67,59 @@ static TResult FoldImpl(IEnumerable source, int count, foreach (var e in AssertCountImpl(source.Index(), count, OnFolderSourceSizeErrorSelector)) elements[e.Key] = e.Value; - return count switch + switch (count) { - 1 => folder1 !(elements[0]), - 2 => folder2 !(elements[0], elements[1]), - 3 => folder3 !(elements[0], elements[1], elements[2]), - 4 => folder4 !(elements[0], elements[1], elements[2], elements[3]), - 5 => folder5 !(elements[0], elements[1], elements[2], elements[3], elements[4]), - 6 => folder6 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]), - 7 => folder7 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]), - 8 => folder8 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]), - 9 => folder9 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]), - 10 => folder10!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]), - 11 => folder11!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10]), - 12 => folder12!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11]), - 13 => folder13!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12]), - 14 => folder14!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13]), - 15 => folder15!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14]), - 16 => folder16!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14], elements[15]), - _ => throw new NotSupportedException() - }; + case 1: + Debug.Assert(folder1 is not null); + return folder1(elements[0]); + case 2: + Debug.Assert(folder2 is not null); + return folder2(elements[0], elements[1]); + case 3: + Debug.Assert(folder3 is not null); + return folder3(elements[0], elements[1], elements[2]); + case 4: + Debug.Assert(folder4 is not null); + return folder4(elements[0], elements[1], elements[2], elements[3]); + case 5: + Debug.Assert(folder5 is not null); + return folder5(elements[0], elements[1], elements[2], elements[3], elements[4]); + case 6: + Debug.Assert(folder6 is not null); + return folder6(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]); + case 7: + Debug.Assert(folder7 is not null); + return folder7(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]); + case 8: + Debug.Assert(folder8 is not null); + return folder8(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]); + case 9: + Debug.Assert(folder9 is not null); + return folder9(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]); + case 10: + Debug.Assert(folder10 is not null); + return folder10(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]); + case 11: + Debug.Assert(folder11 is not null); + return folder11(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10]); + case 12: + Debug.Assert(folder12 is not null); + return folder12(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11]); + case 13: + Debug.Assert(folder13 is not null); + return folder13(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12]); + case 14: + Debug.Assert(folder14 is not null); + return folder14(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13]); + case 15: + Debug.Assert(folder15 is not null); + return folder15(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14]); + case 16: + Debug.Assert(folder16 is not null); + return folder16(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14], elements[15]); + default: + throw new NotSupportedException(); + } } static readonly Func OnFolderSourceSizeErrorSelector = OnFolderSourceSizeError; diff --git a/MoreLinq/Lookup.cs b/MoreLinq/Lookup.cs index 8ee430a64..27ca13e15 100644 --- a/MoreLinq/Lookup.cs +++ b/MoreLinq/Lookup.cs @@ -24,12 +24,6 @@ // SOFTWARE. #endregion -#if !NET6_0_OR_GREATER -#nullable enable annotations -#pragma warning disable 8602 // Dereference of a possibly null reference. -#pragma warning disable 8603 // Possible null reference return. -#endif - namespace MoreLinq { using System; @@ -65,7 +59,11 @@ internal static Lookup Create(IEnumerable sour var lookup = new Lookup(comparer); foreach (var item in source) - lookup.GetGrouping(keySelector(item), create: true)!.Add(elementSelector(item)); + { + var grouping = lookup.GetGrouping(keySelector(item), create: true); + Debug.Assert(grouping is not null); + grouping.Add(elementSelector(item)); + } return lookup; } @@ -78,7 +76,11 @@ internal static Lookup Create(IEnumerable source, Func var lookup = new Lookup(comparer); foreach (var item in source) - lookup.GetGrouping(keySelector(item), create: true)!.Add(item); + { + var grouping = lookup.GetGrouping(keySelector(item), create: true); + Debug.Assert(grouping is not null); + grouping.Add(item); + } return lookup; } @@ -90,7 +92,11 @@ internal static Lookup CreateForJoin(IEnumerable sourc foreach (var item in source) { if (keySelector(item) is { } key) - lookup.GetGrouping(key, create: true)!.Add(item); + { + var grouping = lookup.GetGrouping(key, create: true); + Debug.Assert(grouping is not null); + grouping.Add(item); + } } return lookup; @@ -179,10 +185,12 @@ void Resize() { var newSize = checked((_count * 2) + 1); var newGroupings = new Grouping[newSize]; - var g = _lastGrouping!; + var g = _lastGrouping; + Debug.Assert(g is not null); do { - g = g._next!; + g = g._next; + Debug.Assert(g is not null); var index = g._hashCode % newSize; g._hashNext = newGroupings[index]; newGroupings[index] = g; diff --git a/MoreLinq/Pad.cs b/MoreLinq/Pad.cs index e046b262b..9fc728c35 100644 --- a/MoreLinq/Pad.cs +++ b/MoreLinq/Pad.cs @@ -19,7 +19,6 @@ namespace MoreLinq { using System; using System.Collections.Generic; - using System.Diagnostics; static partial class MoreEnumerable { diff --git a/MoreLinq/PartialSort.cs b/MoreLinq/PartialSort.cs index e8010510f..6e15de698 100644 --- a/MoreLinq/PartialSort.cs +++ b/MoreLinq/PartialSort.cs @@ -242,7 +242,8 @@ static IEnumerable PartialSortByImpl( { if (keys != null) { - var key = keySelector!(item); + Debug.Assert(keySelector is not null); + var key = keySelector(item); if (Insert(keys, key, keyComparer) is {} i) { if (top.Count == count) diff --git a/MoreLinq/Partition.cs b/MoreLinq/Partition.cs index 3b67ab6b3..047c48c0f 100644 --- a/MoreLinq/Partition.cs +++ b/MoreLinq/Partition.cs @@ -19,7 +19,6 @@ namespace MoreLinq { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Linq; static partial class MoreEnumerable diff --git a/MoreLinq/Reactive/Subject.cs b/MoreLinq/Reactive/Subject.cs index 2f01e8047..f1fc91a6a 100644 --- a/MoreLinq/Reactive/Subject.cs +++ b/MoreLinq/Reactive/Subject.cs @@ -116,12 +116,12 @@ public void OnNext(T value) } public void OnError(Exception error) => - OnFinality(ref _error, error, (observer, err) => observer.OnError(err!)); + OnFinality(ref _error, error, (observer, err) => observer.OnError(err)); public void OnCompleted() => OnFinality(ref _completed, true, (observer, _) => observer.OnCompleted()); - void OnFinality(ref TState state, TState value, Action, TState> action) + void OnFinality(ref TState? state, TState value, Action, TState> action) { if (IsMuted) return; From 215f6fde8cceab9864ffae8461799c174575ce12 Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Wed, 16 Nov 2022 18:49:21 +0100 Subject: [PATCH 2/3] Revert unrelated changes to "Subject" --- MoreLinq/Reactive/Subject.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MoreLinq/Reactive/Subject.cs b/MoreLinq/Reactive/Subject.cs index f1fc91a6a..2f01e8047 100644 --- a/MoreLinq/Reactive/Subject.cs +++ b/MoreLinq/Reactive/Subject.cs @@ -116,12 +116,12 @@ public void OnNext(T value) } public void OnError(Exception error) => - OnFinality(ref _error, error, (observer, err) => observer.OnError(err)); + OnFinality(ref _error, error, (observer, err) => observer.OnError(err!)); public void OnCompleted() => OnFinality(ref _completed, true, (observer, _) => observer.OnCompleted()); - void OnFinality(ref TState? state, TState value, Action, TState> action) + void OnFinality(ref TState state, TState value, Action, TState> action) { if (IsMuted) return; From 7e6fa33d1ea58325480998943cbfcf8cb9ca9a33 Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Wed, 16 Nov 2022 18:54:08 +0100 Subject: [PATCH 3/3] Make null ref assumption explicit --- MoreLinq.Test/FallbackIfEmptyTest.cs | 8 ++++ MoreLinq/Assume.cs | 31 ++++++++++++ MoreLinq/Experimental/Await.cs | 10 ++-- MoreLinq/Experimental/Memoize.cs | 5 +- MoreLinq/FallbackIfEmpty.cs | 24 ++-------- MoreLinq/Fold.cs | 71 ++++++++-------------------- MoreLinq/Lookup.cs | 19 +++----- MoreLinq/PartialSort.cs | 3 +- 8 files changed, 73 insertions(+), 98 deletions(-) create mode 100644 MoreLinq/Assume.cs diff --git a/MoreLinq.Test/FallbackIfEmptyTest.cs b/MoreLinq.Test/FallbackIfEmptyTest.cs index b8e6b7516..cf6a2df83 100644 --- a/MoreLinq.Test/FallbackIfEmptyTest.cs +++ b/MoreLinq.Test/FallbackIfEmptyTest.cs @@ -60,5 +60,13 @@ public void FallbackIfEmptyPreservesFallbackCollectionIfPossible(SourceKind sour Assert.AreSame(source.FallbackIfEmpty(fallback), fallback); Assert.AreSame(source.FallbackIfEmpty(fallback.AsEnumerable()), fallback); } + + [Test] + public void FallbackIfEmptyWithEmptyNullableSequence() + { + var source = Enumerable.Empty().Select(x => x); + var fallback = (int?)null; + source.FallbackIfEmpty(fallback).AssertSequenceEqual(fallback); + } } } diff --git a/MoreLinq/Assume.cs b/MoreLinq/Assume.cs new file mode 100644 index 000000000..08b60162a --- /dev/null +++ b/MoreLinq/Assume.cs @@ -0,0 +1,31 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2022 Atif Aziz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System.Runtime.CompilerServices; + + static class Assume + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T NotNull(T? obj) where T : class + { + Debug.Assert(obj is not null); + return obj; + } + } +} diff --git a/MoreLinq/Experimental/Await.cs b/MoreLinq/Experimental/Await.cs index d4edbe18f..3873754ea 100644 --- a/MoreLinq/Experimental/Await.cs +++ b/MoreLinq/Experimental/Await.cs @@ -527,19 +527,15 @@ void PostNotice(Notice notice, catch (OperationCanceledException e) when (e.CancellationToken == consumerCancellationTokenSource.Token) { var (error1, error2) = lastCriticalErrors; - Debug.Assert(error1 is not null); throw new Exception("One or more critical errors have occurred.", - error2 != null ? new AggregateException(error1, error2) - : new AggregateException(error1)); + error2 != null ? new AggregateException(Assume.NotNull(error1), error2) + : new AggregateException(Assume.NotNull(error1))); } var (kind, result, error) = notice.Current; if (kind == Notice.Error) - { - Debug.Assert(error is not null); - error.Throw(); - } + Assume.NotNull(error).Throw(); if (kind == Notice.End) break; diff --git a/MoreLinq/Experimental/Memoize.cs b/MoreLinq/Experimental/Memoize.cs index 626564c45..da261b1a2 100644 --- a/MoreLinq/Experimental/Memoize.cs +++ b/MoreLinq/Experimental/Memoize.cs @@ -115,10 +115,7 @@ public IEnumerator GetEnumerator() if (index >= _cache.Count) { if (index == _errorIndex) - { - Debug.Assert(_error is not null); - _error.Throw(); - } + Assume.NotNull(_error).Throw(); if (_sourceEnumerator == null) break; diff --git a/MoreLinq/FallbackIfEmpty.cs b/MoreLinq/FallbackIfEmpty.cs index 9c3aaab3d..30a16726e 100644 --- a/MoreLinq/FallbackIfEmpty.cs +++ b/MoreLinq/FallbackIfEmpty.cs @@ -189,26 +189,10 @@ IEnumerable FallbackOnArgs() { Debug.Assert(count is >= 1 and <= 4); - Debug.Assert(fallback1 is not null); - yield return fallback1; - - if (count > 1) - { - Debug.Assert(fallback2 is not null); - yield return fallback2; - } - - if (count > 2) - { - Debug.Assert(fallback3 is not null); - yield return fallback3; - } - - if (count > 3) - { - Debug.Assert(fallback4 is not null); - yield return fallback4; - } + yield return fallback1!; + if (count > 1) yield return fallback2!; + if (count > 2) yield return fallback3!; + if (count > 3) yield return fallback4!; } } } diff --git a/MoreLinq/Fold.cs b/MoreLinq/Fold.cs index c5ac37916..31fa1bbef 100644 --- a/MoreLinq/Fold.cs +++ b/MoreLinq/Fold.cs @@ -67,59 +67,26 @@ static TResult FoldImpl(IEnumerable source, int count, foreach (var e in AssertCountImpl(source.Index(), count, OnFolderSourceSizeErrorSelector)) elements[e.Key] = e.Value; - switch (count) + return count switch { - case 1: - Debug.Assert(folder1 is not null); - return folder1(elements[0]); - case 2: - Debug.Assert(folder2 is not null); - return folder2(elements[0], elements[1]); - case 3: - Debug.Assert(folder3 is not null); - return folder3(elements[0], elements[1], elements[2]); - case 4: - Debug.Assert(folder4 is not null); - return folder4(elements[0], elements[1], elements[2], elements[3]); - case 5: - Debug.Assert(folder5 is not null); - return folder5(elements[0], elements[1], elements[2], elements[3], elements[4]); - case 6: - Debug.Assert(folder6 is not null); - return folder6(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]); - case 7: - Debug.Assert(folder7 is not null); - return folder7(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]); - case 8: - Debug.Assert(folder8 is not null); - return folder8(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]); - case 9: - Debug.Assert(folder9 is not null); - return folder9(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]); - case 10: - Debug.Assert(folder10 is not null); - return folder10(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]); - case 11: - Debug.Assert(folder11 is not null); - return folder11(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10]); - case 12: - Debug.Assert(folder12 is not null); - return folder12(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11]); - case 13: - Debug.Assert(folder13 is not null); - return folder13(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12]); - case 14: - Debug.Assert(folder14 is not null); - return folder14(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13]); - case 15: - Debug.Assert(folder15 is not null); - return folder15(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14]); - case 16: - Debug.Assert(folder16 is not null); - return folder16(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14], elements[15]); - default: - throw new NotSupportedException(); - } + 1 => Assume.NotNull(folder1 )(elements[0]), + 2 => Assume.NotNull(folder2 )(elements[0], elements[1]), + 3 => Assume.NotNull(folder3 )(elements[0], elements[1], elements[2]), + 4 => Assume.NotNull(folder4 )(elements[0], elements[1], elements[2], elements[3]), + 5 => Assume.NotNull(folder5 )(elements[0], elements[1], elements[2], elements[3], elements[4]), + 6 => Assume.NotNull(folder6 )(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]), + 7 => Assume.NotNull(folder7 )(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]), + 8 => Assume.NotNull(folder8 )(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]), + 9 => Assume.NotNull(folder9 )(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]), + 10 => Assume.NotNull(folder10)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]), + 11 => Assume.NotNull(folder11)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10]), + 12 => Assume.NotNull(folder12)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11]), + 13 => Assume.NotNull(folder13)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12]), + 14 => Assume.NotNull(folder14)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13]), + 15 => Assume.NotNull(folder15)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14]), + 16 => Assume.NotNull(folder16)(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9], elements[10], elements[11], elements[12], elements[13], elements[14], elements[15]), + _ => throw new NotSupportedException() + }; } static readonly Func OnFolderSourceSizeErrorSelector = OnFolderSourceSizeError; diff --git a/MoreLinq/Lookup.cs b/MoreLinq/Lookup.cs index 27ca13e15..a25b104ec 100644 --- a/MoreLinq/Lookup.cs +++ b/MoreLinq/Lookup.cs @@ -60,8 +60,7 @@ internal static Lookup Create(IEnumerable sour foreach (var item in source) { - var grouping = lookup.GetGrouping(keySelector(item), create: true); - Debug.Assert(grouping is not null); + var grouping = Assume.NotNull(lookup.GetGrouping(keySelector(item), create: true)); grouping.Add(elementSelector(item)); } @@ -77,8 +76,7 @@ internal static Lookup Create(IEnumerable source, Func foreach (var item in source) { - var grouping = lookup.GetGrouping(keySelector(item), create: true); - Debug.Assert(grouping is not null); + var grouping = Assume.NotNull(lookup.GetGrouping(keySelector(item), create: true)); grouping.Add(item); } @@ -93,8 +91,7 @@ internal static Lookup CreateForJoin(IEnumerable sourc { if (keySelector(item) is { } key) { - var grouping = lookup.GetGrouping(key, create: true); - Debug.Assert(grouping is not null); + var grouping = Assume.NotNull(lookup.GetGrouping(key, create: true)); grouping.Add(item); } } @@ -128,9 +125,7 @@ public IEnumerator> GetEnumerator() { do { - g = g._next; - - Debug.Assert(g is not null); + g = Assume.NotNull(g._next); yield return g; } while (g != _lastGrouping); @@ -185,12 +180,10 @@ void Resize() { var newSize = checked((_count * 2) + 1); var newGroupings = new Grouping[newSize]; - var g = _lastGrouping; - Debug.Assert(g is not null); + var g = Assume.NotNull(_lastGrouping); do { - g = g._next; - Debug.Assert(g is not null); + g = Assume.NotNull(g._next); var index = g._hashCode % newSize; g._hashNext = newGroupings[index]; newGroupings[index] = g; diff --git a/MoreLinq/PartialSort.cs b/MoreLinq/PartialSort.cs index 6e15de698..ecf8b1aec 100644 --- a/MoreLinq/PartialSort.cs +++ b/MoreLinq/PartialSort.cs @@ -242,8 +242,7 @@ static IEnumerable PartialSortByImpl( { if (keys != null) { - Debug.Assert(keySelector is not null); - var key = keySelector(item); + var key = Assume.NotNull(keySelector)(item); if (Insert(keys, key, keyComparer) is {} i) { if (top.Count == count)