diff --git a/MoreLinq.Test/MoreLinq.Test.csproj b/MoreLinq.Test/MoreLinq.Test.csproj index ea2da2dde..a08121f0e 100644 --- a/MoreLinq.Test/MoreLinq.Test.csproj +++ b/MoreLinq.Test/MoreLinq.Test.csproj @@ -40,7 +40,6 @@ - diff --git a/MoreLinq/Assert.cs b/MoreLinq/Assert.cs index 722313366..1b272d8ed 100644 --- a/MoreLinq/Assert.cs +++ b/MoreLinq/Assert.cs @@ -60,7 +60,7 @@ public static IEnumerable Assert(this IEnumerable sou /// public static IEnumerable Assert(this IEnumerable source, - Func predicate, Func errorSelector) + Func predicate, Func? errorSelector) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); diff --git a/MoreLinq/Batch.cs b/MoreLinq/Batch.cs index c6db41d82..2b63b3f50 100644 --- a/MoreLinq/Batch.cs +++ b/MoreLinq/Batch.cs @@ -116,7 +116,7 @@ public static IEnumerable Batch(this IEnumerable Batch(int size) { - TSource[] bucket = null; + TSource[]? bucket = null; var count = 0; foreach (var item in source) diff --git a/MoreLinq/CountBy.cs b/MoreLinq/CountBy.cs index 11e22ba29..623fc14a8 100644 --- a/MoreLinq/CountBy.cs +++ b/MoreLinq/CountBy.cs @@ -50,7 +50,7 @@ public static IEnumerable> CountBy(this I /// If null, the default equality comparer for is used. /// A sequence of unique keys and their number of occurrences in the original sequence. - public static IEnumerable> CountBy(this IEnumerable source, Func keySelector, IEqualityComparer comparer) + public static IEnumerable> CountBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -94,8 +94,7 @@ bool TryGetIndex(TKey key, out int i) keys = new List(); counts = new List(); - var havePrevKey = false; - var prevKey = default(TKey); + (bool, TKey) prevKey = (false, default); var index = 0; foreach (var item in source) @@ -103,8 +102,9 @@ bool TryGetIndex(TKey key, out int i) var key = keySelector(item); if (// key same as the previous? then re-use the index - havePrevKey && cmp.GetHashCode(prevKey) == cmp.GetHashCode(key) - && cmp.Equals(prevKey, key) + prevKey is (true, var pk) + && cmp.GetHashCode(pk) == cmp.GetHashCode(key) + && cmp.Equals(pk, key) // otherwise try & find index of the key || TryGetIndex(key, out index)) { @@ -121,8 +121,7 @@ bool TryGetIndex(TKey key, out int i) counts.Add(1); } - prevKey = key; - havePrevKey = true; + prevKey = (true, key); } } } diff --git a/MoreLinq/Delegating.cs b/MoreLinq/Delegating.cs index 6ccbf6885..4b9e8c189 100644 --- a/MoreLinq/Delegating.cs +++ b/MoreLinq/Delegating.cs @@ -33,8 +33,8 @@ public static IDisposable Disposable(Action delegatee) => new DelegatingDisposable(delegatee); public static IObserver Observer(Action onNext, - Action onError = null, - Action onCompleted = null) => + Action? onError = null, + Action? onCompleted = null) => new DelegatingObserver(onNext, onError, onCompleted); } @@ -48,7 +48,7 @@ public DelegatingDisposable(Action delegatee) => public void Dispose() { var delegatee = _delegatee; - if (delegatee == null || Interlocked.CompareExchange(ref _delegatee, null, delegatee) != delegatee) + if (delegatee == null || Interlocked.CompareExchange(ref _delegatee, null!, delegatee) != delegatee) return; delegatee(); } @@ -57,12 +57,12 @@ public void Dispose() sealed class DelegatingObserver : IObserver { readonly Action _onNext; - readonly Action _onError; - readonly Action _onCompleted; + readonly Action? _onError; + readonly Action? _onCompleted; public DelegatingObserver(Action onNext, - Action onError = null, - Action onCompleted = null) + Action? onError = null, + Action? onCompleted = null) { _onNext = onNext ?? throw new ArgumentNullException(nameof(onNext)); _onError = onError; diff --git a/MoreLinq/DistinctBy.cs b/MoreLinq/DistinctBy.cs index c8dc010a4..a05faab82 100644 --- a/MoreLinq/DistinctBy.cs +++ b/MoreLinq/DistinctBy.cs @@ -63,7 +63,7 @@ public static IEnumerable DistinctBy(this IEnumerable public static IEnumerable DistinctBy(this IEnumerable source, - Func keySelector, IEqualityComparer comparer) + Func keySelector, IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); diff --git a/MoreLinq/EndsWith.cs b/MoreLinq/EndsWith.cs index ca1de4e66..c6b449351 100644 --- a/MoreLinq/EndsWith.cs +++ b/MoreLinq/EndsWith.cs @@ -66,7 +66,7 @@ public static bool EndsWith(this IEnumerable first, IEnumerable second) /// elements at the same index. /// - public static bool EndsWith(this IEnumerable first, IEnumerable second, IEqualityComparer comparer) + public static bool EndsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); @@ -77,13 +77,13 @@ public static bool EndsWith(this IEnumerable first, IEnumerable second, return second.TryGetCollectionCount() is int secondCount ? first.TryGetCollectionCount() is int firstCount && secondCount > firstCount ? false - : Impl(second, secondCount) - : Impl(secondList = second.ToList(), secondList.Count); + : Impl(second, secondCount, comparer) + : Impl(secondList = second.ToList(), secondList.Count, comparer); - bool Impl(IEnumerable snd, int count) + bool Impl(IEnumerable snd, int count, IEqualityComparer cmp) { using var firstIter = first.TakeLast(count).GetEnumerator(); - return snd.All(item => firstIter.MoveNext() && comparer.Equals(firstIter.Current, item)); + return snd.All(item => firstIter.MoveNext() && cmp.Equals(firstIter.Current, item)); } } } diff --git a/MoreLinq/EquiZip.cs b/MoreLinq/EquiZip.cs index edede6ef1..e7b990038 100644 --- a/MoreLinq/EquiZip.cs +++ b/MoreLinq/EquiZip.cs @@ -169,15 +169,12 @@ public static IEnumerable EquiZip( } static IEnumerable EquiZipImpl( - IEnumerable s1, - IEnumerable s2, - IEnumerable s3, - IEnumerable s4, + IEnumerable s1, + IEnumerable s2, + IEnumerable? s3, + IEnumerable? s4, Func resultSelector) { - Debug.Assert(s1 != null); - Debug.Assert(s2 != null); - const int zero = 0, one = 1; var limit = 1 + (s3 != null ? one : zero) diff --git a/MoreLinq/ExceptBy.cs b/MoreLinq/ExceptBy.cs index d204ce8b0..d3faa6ea8 100644 --- a/MoreLinq/ExceptBy.cs +++ b/MoreLinq/ExceptBy.cs @@ -73,7 +73,7 @@ public static IEnumerable ExceptBy(this IEnumerable ExceptBy(this IEnumerable first, IEnumerable second, Func keySelector, - IEqualityComparer keyComparer) + IEqualityComparer? keyComparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/Experimental/Await.cs b/MoreLinq/Experimental/Await.cs index 229fccbcb..dd664c1a8 100644 --- a/MoreLinq/Experimental/Await.cs +++ b/MoreLinq/Experimental/Await.cs @@ -28,6 +28,7 @@ namespace MoreLinq.Experimental using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; + using Unit = System.ValueTuple; /// /// Represents options for a query whose results evaluate asynchronously. @@ -436,14 +437,14 @@ IEnumerable _(int? maxConcurrency, TaskScheduler scheduler, bool ordere // BlockingCollection.Add throws if called after CompleteAdding // and we want to deliberately tolerate the race condition. - var notices = new BlockingCollection<(Notice, (int, T, Task), ExceptionDispatchInfo)>(); + var notices = new BlockingCollection<(Notice, (int, T, Task), ExceptionDispatchInfo?)>(); var consumerCancellationTokenSource = new CancellationTokenSource(); - (Exception, Exception) lastCriticalErrors = default; + (Exception?, Exception?) lastCriticalErrors = default; void PostNotice(Notice notice, (int, T, Task) item, - Exception error) + Exception? error) { // If a notice fails to post then assume critical error // conditions (like low memory), capture the error without @@ -532,10 +533,12 @@ await enumerator.StartAsync( : new AggregateException(error1)); } - var (kind, result, error) = notice.Current; + (Notice kind, (int, T, Task) result, ExceptionDispatchInfo? error) = notice.Current; if (kind == Notice.Error) - error.Throw(); + { + error?.Throw(); + } if (kind == Notice.End) break; @@ -584,7 +587,7 @@ await enumerator.StartAsync( } } - if (holds?.Count > 0) // yield any withheld, which should be in order... + if (holds != null && holds.Count > 0) // yield any withheld, which should be in order... { foreach (var (key, x, value) in holds) { @@ -688,7 +691,7 @@ static class AwaitQuery public static IAwaitQuery Create( Func> impl, - AwaitQueryOptions options = null) => + AwaitQueryOptions? options = null) => new AwaitQuery(impl, options); } @@ -697,7 +700,7 @@ sealed class AwaitQuery : IAwaitQuery readonly Func> _impl; public AwaitQuery(Func> impl, - AwaitQueryOptions options = null) + AwaitQueryOptions? options = null) { _impl = impl; Options = options ?? AwaitQueryOptions.Default; @@ -735,8 +738,8 @@ static class CompletedTask static CompletedTask() { - var tcs = new TaskCompletionSource(); - tcs.SetResult(null); + var tcs = new TaskCompletionSource(); + tcs.SetResult(default); Instance = tcs.Task; } @@ -751,9 +754,9 @@ sealed class ConcurrencyGate { public static readonly ConcurrencyGate Unbounded = new ConcurrencyGate(); - readonly SemaphoreSlim _semaphore; + readonly SemaphoreSlim? _semaphore; - ConcurrencyGate(SemaphoreSlim semaphore = null) => + ConcurrencyGate(SemaphoreSlim? semaphore = null) => _semaphore = semaphore; public ConcurrencyGate(int max) : diff --git a/MoreLinq/Experimental/Memoize.cs b/MoreLinq/Experimental/Memoize.cs index 65d309fda..a6dcad91b 100644 --- a/MoreLinq/Experimental/Memoize.cs +++ b/MoreLinq/Experimental/Memoize.cs @@ -20,6 +20,7 @@ namespace MoreLinq.Experimental using System; using System.Collections; using System.Collections.Generic; + using System.Diagnostics; using System.Runtime.ExceptionServices; static partial class ExperimentalEnumerable @@ -62,12 +63,12 @@ public static IEnumerable Memoize(this IEnumerable source) sealed class MemoizedEnumerable : IEnumerable, IDisposable { - List _cache; + List? _cache; readonly object _locker; readonly IEnumerable _source; - IEnumerator _sourceEnumerator; + IEnumerator? _sourceEnumerator; int? _errorIndex; - ExceptionDispatchInfo _error; + ExceptionDispatchInfo? _error; public MemoizedEnumerable(IEnumerable sequence) { @@ -115,7 +116,9 @@ public IEnumerator GetEnumerator() if (index >= _cache.Count) { if (index == _errorIndex) - _error.Throw(); + { + _error?.Throw(); + } if (_sourceEnumerator == null) break; diff --git a/MoreLinq/Extensions.ToDataTable.g.cs b/MoreLinq/Extensions.ToDataTable.g.cs index 7931061c6..e938397a0 100644 --- a/MoreLinq/Extensions.ToDataTable.g.cs +++ b/MoreLinq/Extensions.ToDataTable.g.cs @@ -17,6 +17,8 @@ // This code was generated by a tool. Any changes made manually will be lost // the next time this code is regenerated. +#nullable enable // TODO(nullable) review why this is needed + namespace MoreLinq.Extensions { using System; diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index 0b1211058..f79e47375 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -17,6 +17,8 @@ // This code was generated by a tool. Any changes made manually will be lost // the next time this code is regenerated. +#nullable enable // TODO(nullable) review why this is needed + namespace MoreLinq.Extensions { using System; @@ -477,7 +479,7 @@ public static IEnumerable Assert(this IEnumerable sou /// public static IEnumerable Assert(this IEnumerable source, - Func predicate, Func errorSelector) + Func predicate, Func? errorSelector) => MoreEnumerable.Assert(source, predicate, errorSelector); } @@ -1174,7 +1176,7 @@ public static IEnumerable> CountBy(this I /// If null, the default equality comparer for is used. /// A sequence of unique keys and their number of occurrences in the original sequence. - public static IEnumerable> CountBy(this IEnumerable source, Func keySelector, IEqualityComparer comparer) + public static IEnumerable> CountBy(this IEnumerable source, Func keySelector, IEqualityComparer? comparer) => MoreEnumerable.CountBy(source, keySelector, comparer); } @@ -1263,7 +1265,7 @@ public static IEnumerable DistinctBy(this IEnumerable public static IEnumerable DistinctBy(this IEnumerable source, - Func keySelector, IEqualityComparer comparer) + Func keySelector, IEqualityComparer? comparer) => MoreEnumerable.DistinctBy(source, keySelector, comparer); } @@ -1314,7 +1316,7 @@ public static bool EndsWith(this IEnumerable first, IEnumerable second) /// elements at the same index. /// - public static bool EndsWith(this IEnumerable first, IEnumerable second, IEqualityComparer comparer) + public static bool EndsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) => MoreEnumerable.EndsWith(first, second, comparer); } @@ -1554,7 +1556,7 @@ public static IEnumerable ExceptBy(this IEnumerable ExceptBy(this IEnumerable first, IEnumerable second, Func keySelector, - IEqualityComparer keyComparer) + IEqualityComparer? keyComparer) => MoreEnumerable.ExceptBy(first, second, keySelector, keyComparer); } @@ -1963,7 +1965,7 @@ public static IEnumerable Flatten(this IEnumerable source, Func /// is null. - public static IEnumerable Flatten(this IEnumerable source, Func selector) + public static IEnumerable Flatten(this IEnumerable source, Func selector) => MoreEnumerable.Flatten(source, selector); } @@ -2533,7 +2535,7 @@ public static IEnumerable FullJoin( Func firstSelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.FullJoin(first, second, keySelector, firstSelector, secondSelector, bothSelector, comparer); /// @@ -2628,7 +2630,7 @@ public static IEnumerable FullJoin( Func firstSelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.FullJoin(first, second, firstKeySelector, secondKeySelector, firstSelector, secondSelector, bothSelector, comparer); } @@ -2693,7 +2695,7 @@ public static IEnumerable> GroupAdjacent public static IEnumerable> GroupAdjacent( this IEnumerable source, Func keySelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.GroupAdjacent(source, keySelector, comparer); /// @@ -2796,7 +2798,7 @@ public static IEnumerable> GroupAdjacent source, Func keySelector, Func elementSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.GroupAdjacent(source, keySelector, elementSelector, comparer); /// @@ -2832,7 +2834,7 @@ public static IEnumerable GroupAdjacent( this IEnumerable source, Func keySelector, Func, TResult> resultSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.GroupAdjacent(source, keySelector, resultSelector, comparer); } @@ -2923,7 +2925,7 @@ public static IEnumerable> IndexBy( this IEnumerable source, Func keySelector, - IEqualityComparer comparer) => MoreEnumerable. IndexBy(source, keySelector, comparer); + IEqualityComparer? comparer) => MoreEnumerable. IndexBy(source, keySelector, comparer); } @@ -3203,7 +3205,7 @@ public static IEnumerable LeftJoin( Func keySelector, Func firstSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.LeftJoin(first, second, keySelector, firstSelector, bothSelector, comparer); /// @@ -3288,7 +3290,7 @@ public static IEnumerable LeftJoin( Func secondKeySelector, Func firstSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.LeftJoin(first, second, firstKeySelector, secondKeySelector, firstSelector, bothSelector, comparer); } @@ -3337,7 +3339,7 @@ public static IExtremaEnumerable MaxBy(this IEnumerable< /// or is null public static IExtremaEnumerable MaxBy(this IEnumerable source, - Func selector, IComparer comparer) + Func selector, IComparer? comparer) => MoreEnumerable.MaxBy(source, selector, comparer); } @@ -3385,7 +3387,7 @@ public static IExtremaEnumerable MinBy(this IEnumerable< /// or is null public static IExtremaEnumerable MinBy(this IEnumerable source, - Func selector, IComparer comparer) + Func selector, IComparer? comparer) => MoreEnumerable.MinBy(source, selector, comparer); } @@ -3454,7 +3456,7 @@ public static IOrderedEnumerable OrderBy(this IEnumerable source, /// A comparer used to define the semantics of element comparison /// An ordered copy of the source sequence - public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer comparer, OrderByDirection direction) + public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) => MoreEnumerable.OrderBy(source, keySelector, comparer, direction); } @@ -3508,7 +3510,7 @@ public static IEnumerable OrderedMerge( public static IEnumerable OrderedMerge( this IEnumerable first, IEnumerable second, - IComparer comparer) + IComparer? comparer) => MoreEnumerable.OrderedMerge(first, second, comparer); /// @@ -3612,7 +3614,7 @@ public static IEnumerable OrderedMerge( Func firstSelector, Func secondSelector, Func bothSelector, - IComparer comparer) + IComparer? comparer) => MoreEnumerable.OrderedMerge(first, second, keySelector, firstSelector, secondSelector, bothSelector, comparer); /// @@ -3701,7 +3703,7 @@ public static IEnumerable OrderedMerge( Func firstSelector, Func secondSelector, Func bothSelector, - IComparer comparer) + IComparer? comparer) => MoreEnumerable.OrderedMerge(first, second, firstKeySelector, secondKeySelector, firstSelector, secondSelector, bothSelector, comparer); } @@ -3976,7 +3978,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// public static IEnumerable PartialSort(this IEnumerable source, - int count, IComparer comparer) + int count, IComparer? comparer) => MoreEnumerable.PartialSort(source, count, comparer); /// @@ -3998,7 +4000,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// public static IEnumerable PartialSort(this IEnumerable source, - int count, IComparer comparer, OrderByDirection direction) + int count, IComparer? comparer, OrderByDirection direction) => MoreEnumerable.PartialSort(source, count, comparer, direction); } @@ -4071,7 +4073,7 @@ public static IEnumerable PartialSortBy( public static IEnumerable PartialSortBy( this IEnumerable source, int count, Func keySelector, - IComparer comparer) + IComparer? comparer) => MoreEnumerable.PartialSortBy(source, count, keySelector, comparer); /// @@ -4096,7 +4098,7 @@ public static IEnumerable PartialSortBy( public static IEnumerable PartialSortBy( this IEnumerable source, int count, Func keySelector, - IComparer comparer, + IComparer? comparer, OrderByDirection direction) => MoreEnumerable.PartialSortBy(source, count, keySelector, comparer, direction); @@ -4270,7 +4272,7 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key, IEqualityComparer comparer, + TKey key, IEqualityComparer? comparer, Func, IEnumerable>, TResult> resultSelector) => MoreEnumerable.Partition(source, key, comparer, resultSelector); @@ -4324,7 +4326,7 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key1, TKey key2, IEqualityComparer comparer, + TKey key1, TKey key2, IEqualityComparer? comparer, Func, IEnumerable, IEnumerable>, TResult> resultSelector) => MoreEnumerable.Partition(source, key1, key2, comparer, resultSelector); @@ -4353,7 +4355,7 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key1, TKey key2, TKey key3, IEqualityComparer comparer, + TKey key1, TKey key2, TKey key3, IEqualityComparer? comparer, Func, IEnumerable, IEnumerable, IEnumerable>, TResult> resultSelector) => MoreEnumerable.Partition(source, key1, key2, key3, comparer, resultSelector); } @@ -4577,7 +4579,7 @@ public static IEnumerable RankBy(this IEnumerable s /// An object that defines the comparison semantics for keys used to rank items /// A sequence of position integers representing the ranks of the corresponding items in the sequence - public static IEnumerable RankBy(this IEnumerable source, Func keySelector, IComparer comparer) + public static IEnumerable RankBy(this IEnumerable source, Func keySelector, IComparer? comparer) => MoreEnumerable.RankBy(source, keySelector, comparer); } @@ -4690,7 +4692,7 @@ public static IEnumerable RightJoin( Func keySelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.RightJoin(first, second, keySelector, secondSelector, bothSelector, comparer); /// @@ -4775,7 +4777,7 @@ public static IEnumerable RightJoin( Func secondKeySelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.RightJoin(first, second, firstKeySelector, secondKeySelector, secondSelector, bothSelector, comparer); } @@ -4806,7 +4808,7 @@ public static IEnumerable> RunLengthEncode(this IEnumera /// The comparer used to identify equivalent items /// A sequence of KeyValuePair{T,int} where they key is the element and the value is the occurrence count - public static IEnumerable> RunLengthEncode(this IEnumerable sequence, IEqualityComparer comparer) + public static IEnumerable> RunLengthEncode(this IEnumerable sequence, IEqualityComparer? comparer) => MoreEnumerable.RunLengthEncode(sequence, comparer); } @@ -4933,7 +4935,7 @@ public static IEnumerable> ScanBy keySelector, Func seedSelector, Func accumulator, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.ScanBy(source, keySelector, seedSelector, accumulator, comparer); } @@ -5275,7 +5277,7 @@ public static IEnumerable SortedMerge(this IEnumerableA variable argument array of zero or more other sequences to merge with /// A merged, order-preserving sequence containing al of the elements of the original sequences - public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, IComparer comparer, params IEnumerable[] otherSequences) + public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, IComparer? comparer, params IEnumerable[] otherSequences) => MoreEnumerable.SortedMerge(source, direction, comparer, otherSequences); } @@ -5337,7 +5339,7 @@ public static IEnumerable> Split(this IEnumerable< /// A sequence of splits of elements. public static IEnumerable> Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer) + TSource separator, IEqualityComparer? comparer) => MoreEnumerable.Split(source, separator, comparer); /// @@ -5369,7 +5371,7 @@ public static IEnumerable> Split(this IEnumerable< /// A sequence of splits of elements. public static IEnumerable> Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer, int count) + TSource separator, IEqualityComparer? comparer, int count) => MoreEnumerable.Split(source, separator, comparer, count); /// @@ -5494,7 +5496,7 @@ public static IEnumerable Split(this IEnumerable public static IEnumerable Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer, int count, + TSource separator, IEqualityComparer? comparer, int count, Func, TResult> resultSelector) => MoreEnumerable.Split(source, separator, comparer, count, resultSelector); @@ -5548,7 +5550,7 @@ public static bool StartsWith(this IEnumerable first, IEnumerable secon /// of elements at the same index. /// - public static bool StartsWith(this IEnumerable first, IEnumerable second, IEqualityComparer comparer) + public static bool StartsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) => MoreEnumerable.StartsWith(first, second, comparer); } @@ -5776,7 +5778,7 @@ public static IOrderedEnumerable ThenBy(this IOrderedEnumerable s /// A comparer used to define the semantics of element comparison /// An ordered copy of the source sequence - public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer comparer, OrderByDirection direction) + public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) => MoreEnumerable.ThenBy(source, keySelector, comparer, direction); } @@ -6354,7 +6356,7 @@ public static partial class ToDictionaryExtension /// public static Dictionary ToDictionary(this IEnumerable<(TKey Key, TValue Value)> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.ToDictionary(source, comparer); /// @@ -6372,7 +6374,7 @@ public static Dictionary ToDictionary(this IEnumerab /// public static Dictionary ToDictionary(this IEnumerable> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.ToDictionary(source, comparer); } @@ -6410,7 +6412,7 @@ public static HashSet ToHashSet(this IEnumerable sour /// This evaluates the input sequence completely. /// - public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer comparer) + public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer? comparer) => MoreEnumerable.ToHashSet(source, comparer); } @@ -6464,7 +6466,7 @@ public static partial class ToLookupExtension /// public static ILookup ToLookup(this IEnumerable<(TKey Key, TValue Value)> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.ToLookup(source, comparer); /// @@ -6482,7 +6484,7 @@ public static ILookup ToLookup(this IEnumerable<(TKe /// public static ILookup ToLookup(this IEnumerable> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) => MoreEnumerable.ToLookup(source, comparer); } @@ -6526,7 +6528,7 @@ public static IEnumerable Trace(this IEnumerable sour /// streams the results. /// - public static IEnumerable Trace(this IEnumerable source, string format) + public static IEnumerable Trace(this IEnumerable source, string? format) => MoreEnumerable.Trace(source, format); /// diff --git a/MoreLinq/FallbackIfEmpty.cs b/MoreLinq/FallbackIfEmpty.cs index 7d0c6915a..a22dc1011 100644 --- a/MoreLinq/FallbackIfEmpty.cs +++ b/MoreLinq/FallbackIfEmpty.cs @@ -45,7 +45,7 @@ static partial class MoreEnumerable public static IEnumerable FallbackIfEmpty(this IEnumerable source, T fallback) { if (source == null) throw new ArgumentNullException(nameof(source)); - return FallbackIfEmptyImpl(source, 1, fallback, default, default, default, null); + return FallbackIfEmptyImpl(source, 1, fallback, default!, default!, default!, null); } /// @@ -66,7 +66,7 @@ public static IEnumerable FallbackIfEmpty(this IEnumerable source, T fa public static IEnumerable FallbackIfEmpty(this IEnumerable source, T fallback1, T fallback2) { if (source == null) throw new ArgumentNullException(nameof(source)); - return FallbackIfEmptyImpl(source, 2, fallback1, fallback2, default, default, null); + return FallbackIfEmptyImpl(source, 2, fallback1, fallback2, default!, default!, null); } /// @@ -89,7 +89,7 @@ public static IEnumerable FallbackIfEmpty(this IEnumerable source, T fa public static IEnumerable FallbackIfEmpty(this IEnumerable source, T fallback1, T fallback2, T fallback3) { if (source == null) throw new ArgumentNullException(nameof(source)); - return FallbackIfEmptyImpl(source, 3, fallback1, fallback2, fallback3, default, null); + return FallbackIfEmptyImpl(source, 3, fallback1, fallback2, fallback3, default!, null); } /// @@ -154,12 +154,12 @@ public static IEnumerable FallbackIfEmpty(this IEnumerable source, IEnu { if (source == null) throw new ArgumentNullException(nameof(source)); if (fallback == null) throw new ArgumentNullException(nameof(fallback)); - return FallbackIfEmptyImpl(source, null, default, default, default, default, fallback); + return FallbackIfEmptyImpl(source, null, default!, default!, default!, default!, fallback); } static IEnumerable FallbackIfEmptyImpl(IEnumerable source, int? count, T fallback1, T fallback2, T fallback3, T fallback4, - IEnumerable fallback) + IEnumerable? fallback) { return source.TryGetCollectionCount() is int collectionCount ? collectionCount == 0 ? Fallback() : source @@ -185,7 +185,7 @@ IEnumerable Fallback() { switch (count) { - case null: return fallback; + case null: return fallback!; case int n when n >= 1 && n <= 4: return FallbackOnArgs(); default: throw new ArgumentOutOfRangeException(nameof(count), count, null); } diff --git a/MoreLinq/FillBackward.cs b/MoreLinq/FillBackward.cs index 1b4cc5514..bef75ce1c 100644 --- a/MoreLinq/FillBackward.cs +++ b/MoreLinq/FillBackward.cs @@ -105,9 +105,9 @@ public static IEnumerable FillBackward(this IEnumerable source, Func FillBackwardImpl(IEnumerable source, Func predicate, Func fillSelector) + static IEnumerable FillBackwardImpl(IEnumerable source, Func predicate, Func? fillSelector) { - List blanks = null; + List? blanks = null; foreach (var item in source) { @@ -133,7 +133,7 @@ static IEnumerable FillBackwardImpl(IEnumerable source, Func p } } - if (blanks?.Count > 0) + if (blanks != null && blanks.Count > 0) { foreach (var blank in blanks) yield return blank; diff --git a/MoreLinq/FillForward.cs b/MoreLinq/FillForward.cs index f3561d1fd..dc20668b7 100644 --- a/MoreLinq/FillForward.cs +++ b/MoreLinq/FillForward.cs @@ -104,18 +104,18 @@ public static IEnumerable FillForward(this IEnumerable source, Func FillForwardImpl(IEnumerable source, Func predicate, Func fillSelector) + static IEnumerable FillForwardImpl(IEnumerable source, Func predicate, Func? fillSelector) { var seeded = false; - var seed = default(T); + var seed = default(T)!; foreach (var item in source) { if (predicate(item)) { yield return seeded ? fillSelector != null - ? fillSelector(item, seed) - : seed + ? fillSelector(item, seed!) + : seed! : item; } else diff --git a/MoreLinq/Flatten.cs b/MoreLinq/Flatten.cs index e98466c3e..77f259c9b 100644 --- a/MoreLinq/Flatten.cs +++ b/MoreLinq/Flatten.cs @@ -88,14 +88,14 @@ public static IEnumerable Flatten(this IEnumerable source, Func /// is null. - public static IEnumerable Flatten(this IEnumerable source, Func selector) + public static IEnumerable Flatten(this IEnumerable source, Func selector) { if (source == null) throw new ArgumentNullException(nameof(source)); if (selector == null) throw new ArgumentNullException(nameof(selector)); return _(); IEnumerable _() { - var e = source.GetEnumerator(); + IEnumerator? e = source.GetEnumerator(); var stack = new Stack(); stack.Push(e); diff --git a/MoreLinq/Fold.cs b/MoreLinq/Fold.cs index bc242d758..ae4337292 100644 --- a/MoreLinq/Fold.cs +++ b/MoreLinq/Fold.cs @@ -23,22 +23,22 @@ namespace MoreLinq static partial class MoreEnumerable { static TResult FoldImpl(IEnumerable source, int count, - Func folder1 = null, - Func folder2 = null, - Func folder3 = null, - Func folder4 = null, - Func folder5 = null, - Func folder6 = null, - Func folder7 = null, - Func folder8 = null, - Func folder9 = null, - Func folder10 = null, - Func folder11 = null, - Func folder12 = null, - Func folder13 = null, - Func folder14 = null, - Func folder15 = null, - Func folder16 = null + Func? folder1 = null, + Func? folder2 = null, + Func? folder3 = null, + Func? folder4 = null, + Func? folder5 = null, + Func? folder6 = null, + Func? folder7 = null, + Func? folder8 = null, + Func? folder9 = null, + Func? folder10 = null, + Func? folder11 = null, + Func? folder12 = null, + Func? folder13 = null, + Func? folder14 = null, + Func? folder15 = null, + Func? folder16 = null ) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -69,22 +69,22 @@ static TResult FoldImpl(IEnumerable source, int count, switch (count) { - case 1: return folder1 (elements[0]); - case 2: return folder2 (elements[0], elements[1]); - case 3: return folder3 (elements[0], elements[1], elements[2]); - case 4: return folder4 (elements[0], elements[1], elements[2], elements[3]); - case 5: return folder5 (elements[0], elements[1], elements[2], elements[3], elements[4]); - case 6: return folder6 (elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]); - case 7: return folder7 (elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]); - case 8: return folder8 (elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]); - case 9: return folder9 (elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]); - case 10: return folder10(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]); - case 11: 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: 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: 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: 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: 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: 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]); + case 1: return folder1 !(elements[0]); + case 2: return folder2 !(elements[0], elements[1]); + case 3: return folder3 !(elements[0], elements[1], elements[2]); + case 4: return folder4 !(elements[0], elements[1], elements[2], elements[3]); + case 5: return folder5 !(elements[0], elements[1], elements[2], elements[3], elements[4]); + case 6: return folder6 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]); + case 7: return folder7 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6]); + case 8: return folder8 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7]); + case 9: return folder9 !(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8]); + case 10: return folder10!(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5], elements[6], elements[7], elements[8], elements[9]); + case 11: 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: 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: 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: 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: 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: 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(); } } diff --git a/MoreLinq/FullJoin.cs b/MoreLinq/FullJoin.cs index 5f3f782c2..251cd6ec5 100644 --- a/MoreLinq/FullJoin.cs +++ b/MoreLinq/FullJoin.cs @@ -113,7 +113,7 @@ public static IEnumerable FullJoin( Func firstSelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); return first.FullJoin(second, @@ -218,7 +218,7 @@ public static IEnumerable FullJoin( Func firstSelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/GroupAdjacent.cs b/MoreLinq/GroupAdjacent.cs index 3523bb690..f4d7dbc73 100644 --- a/MoreLinq/GroupAdjacent.cs +++ b/MoreLinq/GroupAdjacent.cs @@ -83,7 +83,7 @@ public static IEnumerable> GroupAdjacent public static IEnumerable> GroupAdjacent( this IEnumerable source, Func keySelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -160,7 +160,7 @@ public static IEnumerable> GroupAdjacent source, Func keySelector, Func elementSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -246,7 +246,7 @@ public static IEnumerable GroupAdjacent( this IEnumerable source, Func keySelector, Func, TResult> resultSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -265,41 +265,35 @@ static IEnumerable GroupAdjacentImpl( Func, TResult> resultSelector, IEqualityComparer comparer) { - Debug.Assert(source != null); - Debug.Assert(keySelector != null); - Debug.Assert(elementSelector != null); - Debug.Assert(resultSelector != null); - Debug.Assert(comparer != null); using var iterator = source.GetEnumerator(); - var group = default(TKey); - var members = (List) null; + var group = default(TKey)!; + var members = (List?) null; while (iterator.MoveNext()) { var key = keySelector(iterator.Current); var element = elementSelector(iterator.Current); - if (members != null && comparer.Equals(group, key)) + if (members != null && comparer.Equals(group!, key)) { members.Add(element); } else { if (members != null) - yield return resultSelector(group, members); + yield return resultSelector(group!, members); group = key; members = new List { element }; } } if (members != null) - yield return resultSelector(group, members); + yield return resultSelector(group!, members); } static IGrouping CreateGroupAdjacentGrouping(TKey key, IList members) { - Debug.Assert(members != null); return Grouping.Create(key, members.IsReadOnly ? members : new ReadOnlyCollection(members)); } @@ -318,7 +312,6 @@ sealed class Grouping : IGrouping public Grouping(TKey key, IEnumerable members) { - Debug.Assert(members != null); Key = key; _members = members; } diff --git a/MoreLinq/IndexBy.cs b/MoreLinq/IndexBy.cs index 1a407b07c..9403c5bec 100644 --- a/MoreLinq/IndexBy.cs +++ b/MoreLinq/IndexBy.cs @@ -69,8 +69,8 @@ public static IEnumerable> IndexBy( this IEnumerable source, Func keySelector, - IEqualityComparer comparer) => - from e in source.ScanBy(keySelector, k => (Index: -1, Item: default(TSource)), (s, k, e) => (s.Index + 1, e), comparer) + IEqualityComparer? comparer) => + from e in source.ScanBy(keySelector, k => (Index: -1, Item: default(TSource)!), (s, k, e) => (s.Index + 1, e), comparer) select new KeyValuePair(e.Value.Index, e.Value.Item); } } diff --git a/MoreLinq/Interleave.cs b/MoreLinq/Interleave.cs index cd19e19a6..9f65c9e22 100644 --- a/MoreLinq/Interleave.cs +++ b/MoreLinq/Interleave.cs @@ -83,13 +83,13 @@ static IEnumerable Interleave(this IEnumerable sequence, ImbalancedInte var sequences = new[] { sequence }.Concat(otherSequences); // produce an iterator collection for all IEnumerable instancess passed to us - var iterators = sequences.Select(e => e.GetEnumerator()).Acquire(); - List> iteratorList = null; + IEnumerator[]? iterators = sequences.Select(e => e.GetEnumerator()).Acquire(); + List>? iteratorList = null; try { iteratorList = new List>(iterators); - iterators = null; + iterators = null; // disown var shouldContinue = true; var consumedIterators = 0; var iterCount = iteratorList.Count; @@ -115,7 +115,7 @@ static IEnumerable Interleave(this IEnumerable sequence, ImbalancedInte switch (imbalanceStrategy) { case ImbalancedInterleaveStrategy.Pad: - var newIter = iteratorList[index] = Generate(default(T), x => default).GetEnumerator(); + var newIter = iteratorList[index] = Generate(default(T)!, x => default!).GetEnumerator(); newIter.MoveNext(); break; @@ -142,8 +142,7 @@ static IEnumerable Interleave(this IEnumerable sequence, ImbalancedInte } finally { - Debug.Assert(iteratorList != null || iterators != null); - foreach (var iter in (iteratorList ?? (IList>) iterators)) + foreach (var iter in iteratorList ?? (IList>) iterators!) iter.Dispose(); } } diff --git a/MoreLinq/Lag.cs b/MoreLinq/Lag.cs index 51cdf5808..533bbeac7 100644 --- a/MoreLinq/Lag.cs +++ b/MoreLinq/Lag.cs @@ -38,7 +38,7 @@ public static partial class MoreEnumerable public static IEnumerable Lag(this IEnumerable source, int offset, Func resultSelector) { - return Lag(source, offset, default, resultSelector); + return Lag(source, offset, default!, resultSelector); } /// diff --git a/MoreLinq/Lead.cs b/MoreLinq/Lead.cs index a354aea30..ba627088c 100644 --- a/MoreLinq/Lead.cs +++ b/MoreLinq/Lead.cs @@ -39,7 +39,7 @@ public static partial class MoreEnumerable public static IEnumerable Lead(this IEnumerable source, int offset, Func resultSelector) { - return Lead(source, offset, default, resultSelector); + return Lead(source, offset, default!, resultSelector); } /// diff --git a/MoreLinq/LeftJoin.cs b/MoreLinq/LeftJoin.cs index d4af068fb..6648dcefc 100644 --- a/MoreLinq/LeftJoin.cs +++ b/MoreLinq/LeftJoin.cs @@ -103,7 +103,7 @@ public static IEnumerable LeftJoin( Func keySelector, Func firstSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); return first.LeftJoin(second, @@ -198,7 +198,7 @@ public static IEnumerable LeftJoin( Func secondKeySelector, Func firstSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/ListLike.cs b/MoreLinq/ListLike.cs index 45f99cc71..e47206de8 100644 --- a/MoreLinq/ListLike.cs +++ b/MoreLinq/ListLike.cs @@ -36,11 +36,11 @@ static class ListLike public static IListLike ToListLike(this IEnumerable source) => source.TryAsListLike() ?? new List(source.ToList()); - public static IListLike TryAsListLike(this IEnumerable source) + public static IListLike? TryAsListLike(this IEnumerable source) => source is null ? throw new ArgumentNullException(nameof(source)) : source is IList list ? new List(list) : source is IReadOnlyList readOnlyList ? new ReadOnlyList(readOnlyList) - : (IListLike) null; + : (IListLike?) null; sealed class List : IListLike { diff --git a/MoreLinq/Lookup.cs b/MoreLinq/Lookup.cs index 7c873a64e..c576d99a2 100644 --- a/MoreLinq/Lookup.cs +++ b/MoreLinq/Lookup.cs @@ -24,6 +24,8 @@ // SOFTWARE. #endregion +#nullable disable + namespace MoreLinq { using System; diff --git a/MoreLinq/MaxBy.cs b/MoreLinq/MaxBy.cs index f9f3ab3f9..23deb92b3 100644 --- a/MoreLinq/MaxBy.cs +++ b/MoreLinq/MaxBy.cs @@ -207,7 +207,7 @@ public static IExtremaEnumerable MaxBy(this IEnumerable< /// or is null public static IExtremaEnumerable MaxBy(this IEnumerable source, - Func selector, IComparer comparer) + Func selector, IComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (selector == null) throw new ArgumentNullException(nameof(selector)); @@ -340,8 +340,8 @@ IEnumerable Extrema() abstract class Extrema { - public virtual TStore New() => default; - public virtual void Restart(ref TStore store) => store = default; + public virtual TStore New() => default!; + public virtual void Restart(ref TStore store) => store = default!; public void Add(ref TStore store, int? limit, T item) { diff --git a/MoreLinq/MinBy.cs b/MoreLinq/MinBy.cs index ed016132b..3a06bcb98 100644 --- a/MoreLinq/MinBy.cs +++ b/MoreLinq/MinBy.cs @@ -62,7 +62,7 @@ public static IExtremaEnumerable MinBy(this IEnumerable< /// or is null public static IExtremaEnumerable MinBy(this IEnumerable source, - Func selector, IComparer comparer) + Func selector, IComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (selector == null) throw new ArgumentNullException(nameof(selector)); diff --git a/MoreLinq/MoreLinq.csproj b/MoreLinq/MoreLinq.csproj index 3ee4f8020..31c10ac3a 100644 --- a/MoreLinq/MoreLinq.csproj +++ b/MoreLinq/MoreLinq.csproj @@ -121,6 +121,7 @@ MoreLINQ Developers. net451;netstandard1.0;netstandard2.0 8 + enable true portable true @@ -245,4 +246,11 @@ + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/MoreLinq/OrderBy.cs b/MoreLinq/OrderBy.cs index 4e5ce8565..9b5c97e18 100644 --- a/MoreLinq/OrderBy.cs +++ b/MoreLinq/OrderBy.cs @@ -49,13 +49,13 @@ public static IOrderedEnumerable OrderBy(this IEnumerable source, /// A comparer used to define the semantics of element comparison /// An ordered copy of the source sequence - public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer comparer, OrderByDirection direction) + public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); return direction == OrderByDirection.Ascending - ? source.OrderBy(keySelector, comparer) - : source.OrderByDescending(keySelector, comparer); + ? source.OrderBy(keySelector, comparer) + : source.OrderByDescending(keySelector, comparer); } /// @@ -84,13 +84,13 @@ public static IOrderedEnumerable ThenBy(this IOrderedEnumerable s /// A comparer used to define the semantics of element comparison /// An ordered copy of the source sequence - public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer comparer, OrderByDirection direction) + public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, IComparer? comparer, OrderByDirection direction) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); return direction == OrderByDirection.Ascending - ? source.ThenBy(keySelector, comparer) - : source.ThenByDescending(keySelector, comparer); + ? source.ThenBy(keySelector, comparer) + : source.ThenByDescending(keySelector, comparer); } } } diff --git a/MoreLinq/OrderedMerge.cs b/MoreLinq/OrderedMerge.cs index bce2a5ac3..bb4551ec7 100644 --- a/MoreLinq/OrderedMerge.cs +++ b/MoreLinq/OrderedMerge.cs @@ -68,7 +68,7 @@ public static IEnumerable OrderedMerge( public static IEnumerable OrderedMerge( this IEnumerable first, IEnumerable second, - IComparer comparer) + IComparer? comparer) { return OrderedMerge(first, second, e => e, f => f, s => s, (a, _) => a, comparer); } @@ -178,7 +178,7 @@ public static IEnumerable OrderedMerge( Func firstSelector, Func secondSelector, Func bothSelector, - IComparer comparer) + IComparer? comparer) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); // Argument name changes to 'firstKeySelector' return OrderedMerge(first, second, keySelector, keySelector, firstSelector, secondSelector, bothSelector, comparer); @@ -272,7 +272,7 @@ public static IEnumerable OrderedMerge( Func firstSelector, Func secondSelector, Func bothSelector, - IComparer comparer) + IComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/Pad.cs b/MoreLinq/Pad.cs index d45f2f380..1d91bb3a4 100644 --- a/MoreLinq/Pad.cs +++ b/MoreLinq/Pad.cs @@ -48,7 +48,7 @@ static partial class MoreEnumerable public static IEnumerable Pad(this IEnumerable source, int width) { - return Pad(source, width, default(TSource)); + return Pad(source, width, default(TSource)!); } /// @@ -111,15 +111,12 @@ public static IEnumerable Pad(this IEnumerable source if (source == null) throw new ArgumentNullException(nameof(source)); if (paddingSelector == null) throw new ArgumentNullException(nameof(paddingSelector)); if (width < 0) throw new ArgumentException(null, nameof(width)); - return PadImpl(source, width, default, paddingSelector); + return PadImpl(source, width, default!, paddingSelector); } static IEnumerable PadImpl(IEnumerable source, - int width, T padding, Func paddingSelector) + int width, T padding, Func? paddingSelector) { - Debug.Assert(source != null); - Debug.Assert(width >= 0); - var count = 0; foreach (var item in source) { diff --git a/MoreLinq/PadStart.cs b/MoreLinq/PadStart.cs index db676b082..bd5e7a5a0 100644 --- a/MoreLinq/PadStart.cs +++ b/MoreLinq/PadStart.cs @@ -47,7 +47,7 @@ static partial class MoreEnumerable public static IEnumerable PadStart(this IEnumerable source, int width) { - return PadStart(source, width, default(TSource)); + return PadStart(source, width, default(TSource)!); } /// @@ -112,11 +112,11 @@ public static IEnumerable PadStart(this IEnumerable s if (source == null) throw new ArgumentNullException(nameof(source)); if (paddingSelector == null) throw new ArgumentNullException(nameof(paddingSelector)); if (width < 0) throw new ArgumentException(null, nameof(width)); - return PadStartImpl(source, width, default, paddingSelector); + return PadStartImpl(source, width, default!, paddingSelector); } static IEnumerable PadStartImpl(IEnumerable source, - int width, T padding, Func paddingSelector) + int width, T padding, Func? paddingSelector) { return source.TryGetCollectionCount() is int collectionCount diff --git a/MoreLinq/PartialSort.cs b/MoreLinq/PartialSort.cs index eb09b545e..34bfd3e36 100644 --- a/MoreLinq/PartialSort.cs +++ b/MoreLinq/PartialSort.cs @@ -82,7 +82,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// public static IEnumerable PartialSort(this IEnumerable source, - int count, IComparer comparer) + int count, IComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return PartialSortByImpl(source, count, null, null, comparer); @@ -107,7 +107,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// public static IEnumerable PartialSort(this IEnumerable source, - int count, IComparer comparer, OrderByDirection direction) + int count, IComparer? comparer, OrderByDirection direction) { comparer ??= Comparer.Default; if (direction == OrderByDirection.Descending) @@ -181,7 +181,7 @@ public static IEnumerable PartialSortBy( public static IEnumerable PartialSortBy( this IEnumerable source, int count, Func keySelector, - IComparer comparer) + IComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -210,7 +210,7 @@ public static IEnumerable PartialSortBy( public static IEnumerable PartialSortBy( this IEnumerable source, int count, Func keySelector, - IComparer comparer, + IComparer? comparer, OrderByDirection direction) { comparer ??= Comparer.Default; @@ -221,21 +221,20 @@ public static IEnumerable PartialSortBy( static IEnumerable PartialSortByImpl( IEnumerable source, int count, - Func keySelector, - IComparer keyComparer, IComparer comparer) + Func? keySelector, + IComparer? keyComparer, + IComparer? comparer) { - Debug.Assert(source != null); - - var keys = keySelector != null ? new List(count) : null; + var keys = keySelector == null ? null : new List(count); var top = new List(count); foreach (var item in source) { int i; - var key = default(TKey); + var key = default(TKey)!; if (keys != null) { - key = keySelector(item); + key = keySelector!(item); i = keys.BinarySearch(key, keyComparer); } else @@ -254,7 +253,7 @@ static IEnumerable PartialSortByImpl( // TODO Stable sorting - keys?.Insert(i, key); + keys?.Insert(i, key!); top.Insert(i, item); } diff --git a/MoreLinq/Partition.cs b/MoreLinq/Partition.cs index 0cda564ab..be4c637e3 100644 --- a/MoreLinq/Partition.cs +++ b/MoreLinq/Partition.cs @@ -174,11 +174,11 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key, IEqualityComparer comparer, + TKey key, IEqualityComparer? comparer, Func, IEnumerable>, TResult> resultSelector) { if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return PartitionImpl(source, 1, key, default, default, comparer, + return PartitionImpl(source, 1, key, default!, default!, comparer, (a, b, c, rest) => resultSelector(a, rest)); } @@ -232,11 +232,11 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key1, TKey key2, IEqualityComparer comparer, + TKey key1, TKey key2, IEqualityComparer? comparer, Func, IEnumerable, IEnumerable>, TResult> resultSelector) { if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return PartitionImpl(source, 2, key1, key2, default, comparer, + return PartitionImpl(source, 2, key1, key2, default!, comparer, (a, b, c, rest) => resultSelector(a, b, rest)); } @@ -292,12 +292,12 @@ public static TResult Partition(this IEnumerable public static TResult Partition(this IEnumerable> source, - TKey key1, TKey key2, TKey key3, IEqualityComparer comparer, + TKey key1, TKey key2, TKey key3, IEqualityComparer? comparer, Func, IEnumerable, IEnumerable, IEnumerable>, TResult> resultSelector) => PartitionImpl(source, 3, key1, key2, key3, comparer, resultSelector); static TResult PartitionImpl(IEnumerable> source, - int count, TKey key1, TKey key2, TKey key3, IEqualityComparer comparer, + int count, TKey key1, TKey key2, TKey key3, IEqualityComparer? comparer, Func, IEnumerable, IEnumerable, IEnumerable>, TResult> resultSelector) { Debug.Assert(count > 0 && count <= 3); @@ -307,7 +307,7 @@ static TResult PartitionImpl(IEnumerable.Default; - List> etc = null; + List>? etc = null; var groups = new[] { diff --git a/MoreLinq/PendNode.cs b/MoreLinq/PendNode.cs index 28ebe8c42..be0e68349 100644 --- a/MoreLinq/PendNode.cs +++ b/MoreLinq/PendNode.cs @@ -62,11 +62,11 @@ sealed class Source : PendNode public IEnumerator GetEnumerator() { var i = 0; - T[] concats = null; // Array for > 4 concatenations - var concat1 = default(T); // Slots for up to 4 concatenations - var concat2 = default(T); - var concat3 = default(T); - var concat4 = default(T); + T[]? concats = null; // Array for > 4 concatenations + var concat1 = default(T)!; // Slots for up to 4 concatenations + var concat2 = default(T)!; + var concat3 = default(T)!; + var concat4 = default(T)!; var current = this; for (; current is Item item; current = item.Next) @@ -108,10 +108,10 @@ public IEnumerator GetEnumerator() if (concats == null) { - if (i == 4) { yield return concat4; i--; } - if (i == 3) { yield return concat3; i--; } - if (i == 2) { yield return concat2; i--; } - if (i == 1) { yield return concat1; i--; } + if (i == 4) { yield return concat4!; i--; } + if (i == 3) { yield return concat3!; i--; } + if (i == 2) { yield return concat2!; i--; } + if (i == 1) { yield return concat1!; i--; } yield break; } diff --git a/MoreLinq/Permutations.cs b/MoreLinq/Permutations.cs index afede3963..3c96161fd 100644 --- a/MoreLinq/Permutations.cs +++ b/MoreLinq/Permutations.cs @@ -73,6 +73,8 @@ class PermutationEnumerator : IEnumerator> IEnumerator _generatorIterator; bool _hasMoreResults; + IList? _current; + public PermutationEnumerator(IEnumerable valueSet) { _valueSet = valueSet.ToArray(); @@ -81,30 +83,34 @@ public PermutationEnumerator(IEnumerable valueSet) // 1) for empty sets and sets of cardinality 1, there exists only a single permutation. // 2) for sets larger than 1 element, the number of nested loops needed is: set.Count-1 _generator = NestedLoops(NextPermutation, Enumerable.Range(2, Math.Max(0, _valueSet.Count - 1))); - Reset(); + Reset(ref _current, ref _generatorIterator, ref _hasMoreResults); } - public void Reset() + public void Reset() => + Reset(ref _current, ref _generatorIterator, ref _hasMoreResults); + + void Reset(ref IList? current, ref IEnumerator generatorIterator, ref bool hasMoreResults) { - _generatorIterator?.Dispose(); + current = null; + generatorIterator?.Dispose(); // restore lexographic ordering of the permutation indexes for (var i = 0; i < _permutation.Length; i++) _permutation[i] = i; // start a newiteration over the nested loop generator - _generatorIterator = _generator.GetEnumerator(); + generatorIterator = _generator.GetEnumerator(); // we must advance the nestedloop iterator to the initial element, // this ensures that we only ever produce N!-1 calls to NextPermutation() - _generatorIterator.MoveNext(); - _hasMoreResults = true; // there's always at least one permutation: the original set itself + generatorIterator.MoveNext(); + hasMoreResults = true; // there's always at least one permutation: the original set itself } - public IList Current { get; private set; } + public IList Current => _current!; object IEnumerator.Current => Current; public bool MoveNext() { - Current = PermuteValueSet(); + _current = PermuteValueSet(); // check if more permutation left to enumerate var prevResult = _hasMoreResults; _hasMoreResults = _generatorIterator.MoveNext(); diff --git a/MoreLinq/Random.cs b/MoreLinq/Random.cs index eaf66bca1..33566a3db 100644 --- a/MoreLinq/Random.cs +++ b/MoreLinq/Random.cs @@ -230,7 +230,7 @@ sealed class GlobalRandom : Random public static readonly Random Instance = new GlobalRandom(); static int _seed = Environment.TickCount; - [ThreadStatic] static Random _threadRandom; + [ThreadStatic] static Random? _threadRandom; static Random ThreadRandom => _threadRandom ??= new Random(Interlocked.Increment(ref _seed)); GlobalRandom() { } diff --git a/MoreLinq/Rank.cs b/MoreLinq/Rank.cs index b0d218276..82b2d6076 100644 --- a/MoreLinq/Rank.cs +++ b/MoreLinq/Rank.cs @@ -72,7 +72,7 @@ public static IEnumerable RankBy(this IEnumerable s /// An object that defines the comparison semantics for keys used to rank items /// A sequence of position integers representing the ranks of the corresponding items in the sequence - public static IEnumerable RankBy(this IEnumerable source, Func keySelector, IComparer comparer) + public static IEnumerable RankBy(this IEnumerable source, Func keySelector, IComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); diff --git a/MoreLinq/Reactive/Observable.cs b/MoreLinq/Reactive/Observable.cs index 405958a0d..0c28c9467 100644 --- a/MoreLinq/Reactive/Observable.cs +++ b/MoreLinq/Reactive/Observable.cs @@ -42,7 +42,7 @@ static partial class Observable /// The subscription, which when disposed, will unsubscribe /// from . - public static IDisposable Subscribe(this IObservable source, Action onNext, Action onError = null, Action onCompleted = null) => + public static IDisposable Subscribe(this IObservable source, Action onNext, Action? onError = null, Action? onCompleted = null) => source == null ? throw new ArgumentNullException(nameof(source)) : source.Subscribe(Delegate.Observer(onNext, onError, onCompleted)); diff --git a/MoreLinq/Reactive/Subject.cs b/MoreLinq/Reactive/Subject.cs index cbb1a9764..bdbdcc7ea 100644 --- a/MoreLinq/Reactive/Subject.cs +++ b/MoreLinq/Reactive/Subject.cs @@ -21,17 +21,27 @@ namespace MoreLinq.Reactive using System.Collections.Generic; using Delegate = Delegating.Delegate; - sealed class Subject : IObservable, IObserver + /// + /// Subject + /// + /// + public sealed class Subject : IObservable, IObserver { - List> _observers; + List>? _observers; bool _completed; - Exception _error; + Exception? _error; bool HasObservers => (_observers?.Count ?? 0) > 0; List> Observers => _observers ??= new List>(); bool IsMuted => _completed || _error != null; + /// + /// Notifies the provider that an observer is to receive notifications. + /// + /// + /// + /// public IDisposable Subscribe(IObserver observer) { if (observer == null) throw new ArgumentNullException(nameof(observer)); @@ -66,7 +76,7 @@ public IDisposable Subscribe(IObserver observer) if (observers[i] == observer) { if (_shouldDeleteObserver) - observers[i] = null; + observers[i] = null!; else observers.RemoveAt(i); break; @@ -77,6 +87,10 @@ public IDisposable Subscribe(IObserver observer) bool _shouldDeleteObserver; // delete (null) or remove an observer? + /// + /// Action OnNext + /// + /// public void OnNext(T value) { if (!HasObservers) @@ -113,9 +127,16 @@ public void OnNext(T value) } } + /// + /// Action for Exception handling + /// + /// public void OnError(Exception error) => OnFinality(ref _error, error, (observer, err) => observer.OnError(err)); + /// + /// Action OnCompleted + /// public void OnCompleted() => OnFinality(ref _completed, true, (observer, _) => observer.OnCompleted()); diff --git a/MoreLinq/RightJoin.cs b/MoreLinq/RightJoin.cs index 3c7fa1738..babbe28c1 100644 --- a/MoreLinq/RightJoin.cs +++ b/MoreLinq/RightJoin.cs @@ -102,7 +102,7 @@ public static IEnumerable RightJoin( Func keySelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); return first.RightJoin(second, @@ -197,7 +197,7 @@ public static IEnumerable RightJoin( Func secondKeySelector, Func secondSelector, Func bothSelector, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/RunLengthEncode.cs b/MoreLinq/RunLengthEncode.cs index d60b9f131..566e97a8a 100644 --- a/MoreLinq/RunLengthEncode.cs +++ b/MoreLinq/RunLengthEncode.cs @@ -45,7 +45,7 @@ public static IEnumerable> RunLengthEncode(this IEnumera /// The comparer used to identify equivalent items /// A sequence of KeyValuePair{T,int} where they key is the element and the value is the occurrence count - public static IEnumerable> RunLengthEncode(this IEnumerable sequence, IEqualityComparer comparer) + public static IEnumerable> RunLengthEncode(this IEnumerable sequence, IEqualityComparer? comparer) { if (sequence == null) throw new ArgumentNullException(nameof(sequence)); diff --git a/MoreLinq/ScanBy.cs b/MoreLinq/ScanBy.cs index 2f5de2e03..5c4c5e165 100644 --- a/MoreLinq/ScanBy.cs +++ b/MoreLinq/ScanBy.cs @@ -78,7 +78,7 @@ public static IEnumerable> ScanBy keySelector, Func seedSelector, Func accumulator, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); if (keySelector == null) throw new ArgumentNullException(nameof(keySelector)); @@ -90,16 +90,23 @@ public static IEnumerable> ScanBy> _(IEqualityComparer comparer) { var stateByKey = new Dictionary(comparer); - var prevKey = (HasValue: false, Value: default(TKey)); - var nullKeyState = (HasValue: false, Value: default(TState)); - var state = default(TState); + (bool, TKey) prevKey = (false, default); + (bool, TState) nullKeyState = (false, default); + var state = default(TState)!; bool TryGetState(TKey key, out TState value) { if (key == null) { - value = nullKeyState.Value; - return nullKeyState.HasValue; + switch (nullKeyState) + { + case (true, var v): + value = v; + return true; + case (false, _): + value = default!; + return false; + } } return stateByKey.TryGetValue(key, out value); @@ -109,17 +116,16 @@ bool TryGetState(TKey key, out TState value) { var key = keySelector(item); - if (!(prevKey.HasValue - // key same as the previous? then re-use the state - && comparer.GetHashCode(prevKey.Value) == comparer.GetHashCode(key) - && comparer.Equals(prevKey.Value, key) - // otherwise try & find state of the key - || TryGetState(key, out state))) - { + var haveState = + // key same as the previous? then re-use the state + prevKey is (true, var pk) && comparer.GetHashCode(pk) == comparer.GetHashCode(key) && comparer.Equals(pk, key) + // otherwise try & find state of the key + || TryGetState(key, out state); + + if (!haveState) state = seedSelector(key); - } - state = accumulator(state, key, item); + state = accumulator(state!, key, item); if (key != null) stateByKey[key] = state; diff --git a/MoreLinq/Segment.cs b/MoreLinq/Segment.cs index 198d8d076..fefee4dd8 100644 --- a/MoreLinq/Segment.cs +++ b/MoreLinq/Segment.cs @@ -80,7 +80,7 @@ public static IEnumerable> Segment(this IEnumerable source, using var iter = source.GetEnumerator(); var segment = new List(); - var prevItem = default(T); + var prevItem = default(T)!; // ensure that the first item is always part // of the first segment. This is an intentional @@ -97,7 +97,7 @@ public static IEnumerable> Segment(this IEnumerable source, { ++index; // check if the item represents the start of a new segment - var isNewSegment = newSegmentPredicate(iter.Current, prevItem, index); + var isNewSegment = newSegmentPredicate(iter.Current, prevItem!, index); prevItem = iter.Current; if (!isNewSegment) diff --git a/MoreLinq/SequenceException.cs b/MoreLinq/SequenceException.cs index 07fcca571..65a025c92 100644 --- a/MoreLinq/SequenceException.cs +++ b/MoreLinq/SequenceException.cs @@ -46,7 +46,7 @@ public SequenceException() : /// /// A message that describes the error. - public SequenceException(string message) : + public SequenceException(string? message) : this(message, null) { } /// @@ -57,7 +57,7 @@ public SequenceException(string message) : /// A message that describes the error. /// The exception that is the cause of the current exception. - public SequenceException(string message, Exception innerException) : + public SequenceException(string? message, Exception? innerException) : base(string.IsNullOrEmpty(message) ? DefaultMessage : message, innerException) { } #if !NO_EXCEPTION_SERIALIZATION diff --git a/MoreLinq/SortedMerge.cs b/MoreLinq/SortedMerge.cs index 7b68a2327..b19273c15 100644 --- a/MoreLinq/SortedMerge.cs +++ b/MoreLinq/SortedMerge.cs @@ -65,7 +65,7 @@ public static IEnumerable SortedMerge(this IEnumerableA variable argument array of zero or more other sequences to merge with /// A merged, order-preserving sequence containing al of the elements of the original sequences - public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, IComparer comparer, params IEnumerable[] otherSequences) + public static IEnumerable SortedMerge(this IEnumerable source, OrderByDirection direction, IComparer? comparer, params IEnumerable[] otherSequences) { if (source == null) throw new ArgumentNullException(nameof(source)); if (otherSequences == null) throw new ArgumentNullException(nameof(otherSequences)); diff --git a/MoreLinq/Split.cs b/MoreLinq/Split.cs index 69b1c5f30..86d6e184b 100644 --- a/MoreLinq/Split.cs +++ b/MoreLinq/Split.cs @@ -108,7 +108,7 @@ public static IEnumerable Split(this IEnumerableA sequence of splits of elements. public static IEnumerable> Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer) + TSource separator, IEqualityComparer? comparer) { return Split(source, separator, comparer, int.MaxValue); } @@ -127,7 +127,7 @@ public static IEnumerable> Split(this IEnumerable< /// A sequence of splits of elements. public static IEnumerable> Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer, int count) + TSource separator, IEqualityComparer? comparer, int count) { return Split(source, separator, comparer, count, s => s); } @@ -175,7 +175,7 @@ public static IEnumerable Split(this IEnumerable public static IEnumerable Split(this IEnumerable source, - TSource separator, IEqualityComparer comparer, int count, + TSource separator, IEqualityComparer? comparer, int count, Func, TResult> resultSelector) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -275,7 +275,7 @@ public static IEnumerable Split(this IEnumerable items = null; + List? items = null; foreach (var item in source) { diff --git a/MoreLinq/StartsWith.cs b/MoreLinq/StartsWith.cs index 2bedebaf0..7e3dd80b1 100644 --- a/MoreLinq/StartsWith.cs +++ b/MoreLinq/StartsWith.cs @@ -68,7 +68,7 @@ public static bool StartsWith(this IEnumerable first, IEnumerable secon /// of elements at the same index. /// - public static bool StartsWith(this IEnumerable first, IEnumerable second, IEqualityComparer comparer) + public static bool StartsWith(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) { if (first == null) throw new ArgumentNullException(nameof(first)); if (second == null) throw new ArgumentNullException(nameof(second)); diff --git a/MoreLinq/ToArrayByIndex.cs b/MoreLinq/ToArrayByIndex.cs index 4bbad61ab..ad0f503c5 100644 --- a/MoreLinq/ToArrayByIndex.cs +++ b/MoreLinq/ToArrayByIndex.cs @@ -121,7 +121,7 @@ public static TResult[] ToArrayByIndex(this IEnumerable source, if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); var lastIndex = -1; - var indexed = (List>) null; + var indexed = (List>?) null; List> Indexed() => indexed ??= new List>(); foreach (var e in source) diff --git a/MoreLinq/ToDataTable.cs b/MoreLinq/ToDataTable.cs index fa2719739..993ba1600 100644 --- a/MoreLinq/ToDataTable.cs +++ b/MoreLinq/ToDataTable.cs @@ -20,10 +20,16 @@ namespace MoreLinq using System; using System.Collections.Generic; using System.Data; + using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; + static class Array + { + public static readonly T[] Empty = new T[0]; + } + static partial class MoreEnumerable { /// @@ -41,7 +47,7 @@ static partial class MoreEnumerable public static TTable ToDataTable(this IEnumerable source, TTable table) where TTable : DataTable { - return ToDataTable(source, table, null); + return ToDataTable(source, table, Array>>.Empty); } /// diff --git a/MoreLinq/ToDelimitedString.cs b/MoreLinq/ToDelimitedString.cs index c46f78f34..c02291c70 100644 --- a/MoreLinq/ToDelimitedString.cs +++ b/MoreLinq/ToDelimitedString.cs @@ -53,10 +53,6 @@ public static string ToDelimitedString(this IEnumerable source static string ToDelimitedStringImpl(IEnumerable source, string delimiter, Func append) { - Debug.Assert(source != null); - Debug.Assert(delimiter != null); - Debug.Assert(append != null); - var sb = new StringBuilder(); var i = 0; diff --git a/MoreLinq/ToDictionary.cs b/MoreLinq/ToDictionary.cs index 82a541317..925dbea7f 100644 --- a/MoreLinq/ToDictionary.cs +++ b/MoreLinq/ToDictionary.cs @@ -53,7 +53,7 @@ public static Dictionary ToDictionary(this IEnumerab /// public static Dictionary ToDictionary(this IEnumerable> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.ToDictionary(e => e.Key, e => e.Value, comparer); @@ -90,7 +90,7 @@ public static Dictionary ToDictionary(this IEnumerab /// public static Dictionary ToDictionary(this IEnumerable<(TKey Key, TValue Value)> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.ToDictionary(e => e.Key, e => e.Value, comparer); diff --git a/MoreLinq/ToHashSet.cs b/MoreLinq/ToHashSet.cs index ef6df582a..7301ed357 100644 --- a/MoreLinq/ToHashSet.cs +++ b/MoreLinq/ToHashSet.cs @@ -53,7 +53,7 @@ public static HashSet ToHashSet(this IEnumerable sour /// This evaluates the input sequence completely. /// - public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer comparer) + public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return new HashSet(source, comparer); diff --git a/MoreLinq/ToLookup.cs b/MoreLinq/ToLookup.cs index 47b8115f6..16436feb1 100644 --- a/MoreLinq/ToLookup.cs +++ b/MoreLinq/ToLookup.cs @@ -53,7 +53,7 @@ public static ILookup ToLookup(this IEnumerable public static ILookup ToLookup(this IEnumerable> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.ToLookup(e => e.Key, e => e.Value, comparer); @@ -90,7 +90,7 @@ public static ILookup ToLookup(this IEnumerable<(TKe /// public static ILookup ToLookup(this IEnumerable<(TKey Key, TValue Value)> source, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.ToLookup(e => e.Key, e => e.Value, comparer); diff --git a/MoreLinq/Trace.cs b/MoreLinq/Trace.cs index 8fac03eda..ff9438a3f 100644 --- a/MoreLinq/Trace.cs +++ b/MoreLinq/Trace.cs @@ -19,7 +19,6 @@ namespace MoreLinq { using System; using System.Collections.Generic; - using System.Diagnostics; static partial class MoreEnumerable { @@ -38,7 +37,7 @@ static partial class MoreEnumerable public static IEnumerable Trace(this IEnumerable source) { - return Trace(source, (string) null); + return Trace(source, (string?) null); } /// @@ -59,7 +58,7 @@ public static IEnumerable Trace(this IEnumerable sour /// streams the results. /// - public static IEnumerable Trace(this IEnumerable source, string format) + public static IEnumerable Trace(this IEnumerable source, string? format) { if (source == null) throw new ArgumentNullException(nameof(source)); @@ -93,9 +92,6 @@ public static IEnumerable Trace(this IEnumerable sour static IEnumerable TraceImpl(IEnumerable source, Func formatter) { - Debug.Assert(source != null); - Debug.Assert(formatter != null); - return source #if !NO_TRACING .Pipe(x => System.Diagnostics.Trace.WriteLine(formatter(x))) diff --git a/MoreLinq/Transpose.cs b/MoreLinq/Transpose.cs index 0234c9224..f3cb02888 100644 --- a/MoreLinq/Transpose.cs +++ b/MoreLinq/Transpose.cs @@ -78,7 +78,7 @@ public static IEnumerable> Transpose(this IEnumerable(this IEnumerable so switch (source.TryGetCollectionCount()) { case 0: - return resultSelector(zero, default); + return resultSelector(zero, default!); case 1: { var item = source switch @@ -116,15 +116,15 @@ public static TResult TrySingle(this IEnumerable so return resultSelector(one, item); } case int _: - return resultSelector(many, default); + return resultSelector(many, default!); default: { using var e = source.GetEnumerator(); if (!e.MoveNext()) - return resultSelector(zero, default); + return resultSelector(zero, default!); var current = e.Current; return !e.MoveNext() ? resultSelector(one, current) - : resultSelector(many, default); + : resultSelector(many, default!); } } } diff --git a/MoreLinq/ZipImpl.cs b/MoreLinq/ZipImpl.cs index 2005660cb..e8775fecc 100644 --- a/MoreLinq/ZipImpl.cs +++ b/MoreLinq/ZipImpl.cs @@ -26,18 +26,18 @@ static partial class MoreEnumerable delegate TResult Folder(params T[] args); static IEnumerable ZipImpl( - IEnumerable s1, - IEnumerable s2, - IEnumerable s3, - IEnumerable s4, + IEnumerable s1, + IEnumerable s2, + IEnumerable? s3, + IEnumerable? s4, Func resultSelector, int limit, - Folder errorSelector = null) + Folder? errorSelector = null) { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; + IEnumerator? e1 = null; + IEnumerator? e2 = null; + IEnumerator? e3 = null; + IEnumerator? e4 = null; var terminations = 0; try @@ -69,10 +69,10 @@ static IEnumerable ZipImpl( e4?.Dispose(); } - T Read(ref IEnumerator e, int n) + T Read(ref IEnumerator? e, int n) { if (e == null || terminations > limit) - return default; + return default!; T value; if (e.MoveNext()) @@ -84,7 +84,7 @@ T Read(ref IEnumerator e, int n) e.Dispose(); e = null; terminations++; - value = default; + value = default!; } if (errorSelector != null && terminations > 0 && terminations < n) diff --git a/MoreLinq/ZipShortest.cs b/MoreLinq/ZipShortest.cs index 06920e2df..0d8039eca 100644 --- a/MoreLinq/ZipShortest.cs +++ b/MoreLinq/ZipShortest.cs @@ -175,8 +175,10 @@ public static IEnumerable ZipShortest( } static IEnumerable ZipImpl( - IEnumerable s1, IEnumerable s2, - IEnumerable s3, IEnumerable s4, + IEnumerable s1, + IEnumerable s2, + IEnumerable? s3, + IEnumerable? s4, Func resultSelector) { return ZipImpl(s1, s2, s3, s4, resultSelector, 0); diff --git a/bld/ExtensionsGenerator/MoreLinq.ExtensionsGenerator.csproj b/bld/ExtensionsGenerator/MoreLinq.ExtensionsGenerator.csproj index b43ac7fd7..65c20908b 100644 --- a/bld/ExtensionsGenerator/MoreLinq.ExtensionsGenerator.csproj +++ b/bld/ExtensionsGenerator/MoreLinq.ExtensionsGenerator.csproj @@ -6,7 +6,7 @@ false - - + + diff --git a/bld/ExtensionsGenerator/Program.cs b/bld/ExtensionsGenerator/Program.cs index 6c7820e9b..52ed4105e 100644 --- a/bld/ExtensionsGenerator/Program.cs +++ b/bld/ExtensionsGenerator/Program.cs @@ -303,6 +303,8 @@ public static partial class {m.Name}Extension // This code was generated by a tool. Any changes made manually will be lost // the next time this code is regenerated. +#nullable enable // TODO(nullable) review why this is needed + namespace MoreLinq.Extensions {{ {string.Join("\n", imports)}