From d684bf868961261bfd3943861460038864a13ab2 Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Thu, 3 Nov 2022 22:11:15 +0100 Subject: [PATCH] Adjust library for .NET 6 target (#860) --- MoreLinq.Test/CountByTest.cs | 12 ++++++++ MoreLinq.Test/ToDataTableTest.cs | 8 ++++++ MoreLinq/Collections/Dictionary.cs | 44 ++++++++++++------------------ MoreLinq/Experimental/Await.cs | 1 + MoreLinq/Extensions.g.cs | 16 +++++------ MoreLinq/MoreLinq.csproj | 6 ++-- MoreLinq/PartialSort.cs | 16 +++++------ MoreLinq/Rank.cs | 12 ++++---- MoreLinq/ReverseComparer.cs | 7 ++++- MoreLinq/ToDataTable.cs | 5 ++-- MoreLinq/Trace.cs | 7 ++--- 11 files changed, 75 insertions(+), 59 deletions(-) diff --git a/MoreLinq.Test/CountByTest.cs b/MoreLinq.Test/CountByTest.cs index 26158260d..ea0e7e8a1 100644 --- a/MoreLinq.Test/CountByTest.cs +++ b/MoreLinq.Test/CountByTest.cs @@ -103,5 +103,17 @@ public void CountByWithSomeNullKeys() KeyValuePair.Create("bar", 2), KeyValuePair.Create("baz", 2)); } + + [Test] + public void CountByWithSomeNullKeysAndEqualityComparer() + { + var result = new[] { "a", "B", null, "c", "A", null, "b", "A" }.CountBy(c => c, StringComparer.OrdinalIgnoreCase); + + result.AssertSequenceEqual( + KeyValuePair.Create("a", 3), + KeyValuePair.Create("B", 2), + KeyValuePair.Create((string)null, 2), + KeyValuePair.Create("c", 1)); + } } } diff --git a/MoreLinq.Test/ToDataTableTest.cs b/MoreLinq.Test/ToDataTableTest.cs index cfc95a224..6281c01f1 100644 --- a/MoreLinq.Test/ToDataTableTest.cs +++ b/MoreLinq.Test/ToDataTableTest.cs @@ -22,6 +22,7 @@ namespace MoreLinq.Test using System.Collections.Generic; using System.Data; using System.Linq.Expressions; + using System.Text.RegularExpressions; using NUnit.Framework; [TestFixture] @@ -115,6 +116,13 @@ public void ToDataTableMemberExpressionIndexer() _testObjects.ToDataTable(t => t[0])); } + [Test] + public void ToDataTableMemberExpressionStatic() + { + AssertThrowsArgument.Exception("lambda", () => + _ = _testObjects.ToDataTable(_ => DateTime.Now)); + } + [Test] public void ToDataTableSchemaInDeclarationOrder() { diff --git a/MoreLinq/Collections/Dictionary.cs b/MoreLinq/Collections/Dictionary.cs index 6366554ab..a325768d8 100644 --- a/MoreLinq/Collections/Dictionary.cs +++ b/MoreLinq/Collections/Dictionary.cs @@ -17,55 +17,45 @@ namespace MoreLinq.Collections { + using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; /// /// A minimal wrapper that - /// allows null keys when is a - /// reference type. + /// allows a null key. /// // Add members if and when needed to keep coverage. sealed class Dictionary { - readonly System.Collections.Generic.Dictionary _dict; - (bool, TValue) _null; + readonly System.Collections.Generic.Dictionary, TValue> _dict; public Dictionary(IEqualityComparer comparer) { - _dict = new System.Collections.Generic.Dictionary(comparer); - _null = default; + var keyComparer = ReferenceEquals(comparer, EqualityComparer.Default) + ? null + : new ValueTupleItemComparer(comparer); + _dict = new System.Collections.Generic.Dictionary, TValue>(keyComparer); } public TValue this[TKey key] { - set - { - if (key is null) - _null = (true, value); - else - _dict[key] = value; - } + get => _dict[ValueTuple.Create(key)]; + set => _dict[ValueTuple.Create(key)] = value; } - public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => + _dict.TryGetValue(ValueTuple.Create(key), out value); + + sealed class ValueTupleItemComparer : IEqualityComparer> { - if (key is null) - { - switch (_null) - { - case (true, var v): - value = v; - return true; - case (false, _): - value = default; - return false; - } - } + readonly IEqualityComparer _comparer; - return _dict.TryGetValue(key, out value); + public ValueTupleItemComparer(IEqualityComparer comparer) => _comparer = comparer; + public bool Equals(ValueTuple x, ValueTuple y) => _comparer.Equals(x.Item1, y.Item1); + public int GetHashCode(ValueTuple obj) => obj.Item1 is { } some ? _comparer.GetHashCode(some) : 0; } } } diff --git a/MoreLinq/Experimental/Await.cs b/MoreLinq/Experimental/Await.cs index 018818f02..e8fb18074 100644 --- a/MoreLinq/Experimental/Await.cs +++ b/MoreLinq/Experimental/Await.cs @@ -528,6 +528,7 @@ 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)); diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index a6910c4a5..af8837030 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -3963,7 +3963,7 @@ public static partial class PartialSortExtension { /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// /// Type of elements in the sequence. @@ -3980,7 +3980,7 @@ public static IEnumerable PartialSort(this IEnumerable source, int coun /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// An additional parameter specifies the direction of the sort /// @@ -4000,7 +4000,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. An additional parameter specifies how the /// elements compare to each other. /// @@ -4020,7 +4020,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// Additional parameters specify how the elements compare to each other and /// the direction of the sort. @@ -4050,7 +4050,7 @@ public static partial class PartialSortByExtension /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// /// Type of elements in the sequence. /// Type of keys. @@ -4070,7 +4070,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// An additional parameter specifies the direction of the sort /// /// Type of elements in the sequence. @@ -4092,7 +4092,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// An additional parameter specifies how the keys compare to each other. /// /// Type of elements in the sequence. @@ -4115,7 +4115,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// Additional parameters specify how the elements compare to each other and /// the direction of the sort. /// diff --git a/MoreLinq/MoreLinq.csproj b/MoreLinq/MoreLinq.csproj index e08281ccb..3f5a89681 100644 --- a/MoreLinq/MoreLinq.csproj +++ b/MoreLinq/MoreLinq.csproj @@ -119,7 +119,7 @@ en-US 3.3.2 MoreLINQ Developers. - net451;netstandard1.0;netstandard2.0 + net451;netstandard1.0;netstandard2.0;net6.0 enable @@ -188,12 +188,12 @@ - + $(DefineConstants);MORELINQ - $(DefineConstants);MORELINQ;NO_SERIALIZATION_ATTRIBUTES;NO_EXCEPTION_SERIALIZATION;NO_TRACING;NO_COM;NO_ASYNC + $(DefineConstants);NO_SERIALIZATION_ATTRIBUTES;NO_EXCEPTION_SERIALIZATION;NO_TRACING;NO_COM;NO_ASYNC diff --git a/MoreLinq/PartialSort.cs b/MoreLinq/PartialSort.cs index 60076133a..e8010510f 100644 --- a/MoreLinq/PartialSort.cs +++ b/MoreLinq/PartialSort.cs @@ -25,7 +25,7 @@ static partial class MoreEnumerable { /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// /// Type of elements in the sequence. @@ -44,7 +44,7 @@ public static IEnumerable PartialSort(this IEnumerable source, int coun /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// An additional parameter specifies the direction of the sort /// @@ -66,7 +66,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. An additional parameter specifies how the /// elements compare to each other. /// @@ -89,7 +89,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// /// Combines , - /// where each element is its key, and + /// where each element is its key, and /// in a single operation. /// Additional parameters specify how the elements compare to each other and /// the direction of the sort. @@ -116,7 +116,7 @@ public static IEnumerable PartialSort(this IEnumerable source, /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// /// Type of elements in the sequence. /// Type of keys. @@ -138,7 +138,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// An additional parameter specifies the direction of the sort /// /// Type of elements in the sequence. @@ -162,7 +162,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// An additional parameter specifies how the keys compare to each other. /// /// Type of elements in the sequence. @@ -189,7 +189,7 @@ public static IEnumerable PartialSortBy( /// /// Combines , - /// and in a single operation. + /// and in a single operation. /// Additional parameters specify how the elements compare to each other and /// the direction of the sort. /// diff --git a/MoreLinq/Rank.cs b/MoreLinq/Rank.cs index 82b2d6076..5dff3d13c 100644 --- a/MoreLinq/Rank.cs +++ b/MoreLinq/Rank.cs @@ -83,11 +83,13 @@ IEnumerable _(IComparer comparer) { source = source.ToArray(); // avoid enumerating source twice - var rankDictionary = source.Distinct() - .OrderByDescending(keySelector, comparer) - .Index(1) - .ToDictionary(item => item.Value, - item => item.Key); + var rankDictionary = new Collections.Dictionary(EqualityComparer.Default); + var i = 1; + foreach (var item in source.Distinct() + .OrderByDescending(keySelector, comparer)) + { + rankDictionary[item] = i++; + } // The following loop should not be be converted to a query to // keep this RankBy lazy. diff --git a/MoreLinq/ReverseComparer.cs b/MoreLinq/ReverseComparer.cs index bb46d3da5..00086383d 100644 --- a/MoreLinq/ReverseComparer.cs +++ b/MoreLinq/ReverseComparer.cs @@ -28,7 +28,12 @@ public ReverseComparer(IComparer? underlying) _underlying = underlying ?? Comparer.Default; } - public int Compare(T x, T y) + public int Compare +#if NETCOREAPP3_1_OR_GREATER + (T? x, T? y) +#else + (T x, T y) +#endif { var result = _underlying.Compare(x, y); return result < 0 ? 1 : result > 0 ? -1 : 0; diff --git a/MoreLinq/ToDataTable.cs b/MoreLinq/ToDataTable.cs index dfbf0eca2..bf309642e 100644 --- a/MoreLinq/ToDataTable.cs +++ b/MoreLinq/ToDataTable.cs @@ -169,9 +169,8 @@ MemberInfo GetAccessedMember(LambdaExpression lambda) // Check if the member expression is valid and is a "first level" // member access e.g. not a.b.c - return body is MemberExpression memberExpression - && memberExpression.Expression.NodeType == ExpressionType.Parameter - ? memberExpression.Member + return body is MemberExpression { Expression.NodeType: ExpressionType.Parameter, Member: var member } + ? member : throw new ArgumentException($"Illegal expression: {lambda}", nameof(lambda)); } } diff --git a/MoreLinq/Trace.cs b/MoreLinq/Trace.cs index ff9438a3f..768f9b0f1 100644 --- a/MoreLinq/Trace.cs +++ b/MoreLinq/Trace.cs @@ -62,10 +62,9 @@ public static IEnumerable Trace(this IEnumerable sour { if (source == null) throw new ArgumentNullException(nameof(source)); - return TraceImpl(source, - string.IsNullOrEmpty(format) - ? (Func) (x => x == null ? string.Empty : x.ToString()) - : (x => string.Format(format, x))); + return TraceImpl(source, string.IsNullOrEmpty(format) + ? x => x?.ToString() ?? string.Empty + : x => string.Format(format, x)); } ///