Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust library for .NET 6 target #860

Merged
merged 4 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions MoreLinq.Test/CountByTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
8 changes: 8 additions & 0 deletions MoreLinq.Test/ToDataTableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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()
{
Expand Down
44 changes: 17 additions & 27 deletions MoreLinq/Collections/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,45 @@

namespace MoreLinq.Collections
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// A minimal <see cref="System.Collections.Generic.Dictionary{TKey,TValue}"/> wrapper that
/// allows null keys when <typeparamref name="TKey"/> is a
/// reference type.
/// allows a null key.
/// </summary>

// Add members if and when needed to keep coverage.

sealed class Dictionary<TKey, TValue>
{
readonly System.Collections.Generic.Dictionary<TKey, TValue> _dict;
(bool, TValue) _null;
readonly System.Collections.Generic.Dictionary<ValueTuple<TKey>, TValue> _dict;

public Dictionary(IEqualityComparer<TKey> comparer)
{
_dict = new System.Collections.Generic.Dictionary<TKey, TValue>(comparer);
_null = default;
var keyComparer = ReferenceEquals(comparer, EqualityComparer<TKey>.Default)
? null
: new ValueTupleItemComparer<TKey>(comparer);
_dict = new System.Collections.Generic.Dictionary<ValueTuple<TKey>, 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<T> : IEqualityComparer<ValueTuple<T>>
{
if (key is null)
{
switch (_null)
{
case (true, var v):
value = v;
return true;
case (false, _):
value = default;
return false;
}
}
readonly IEqualityComparer<T> _comparer;

return _dict.TryGetValue(key, out value);
public ValueTupleItemComparer(IEqualityComparer<T> comparer) => _comparer = comparer;
public bool Equals(ValueTuple<T> x, ValueTuple<T> y) => _comparer.Equals(x.Item1, y.Item1);
public int GetHashCode(ValueTuple<T> obj) => obj.Item1 is { } some ? _comparer.GetHashCode(some) : 0;
}
}
}
1 change: 1 addition & 0 deletions MoreLinq/Experimental/Await.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
16 changes: 8 additions & 8 deletions MoreLinq/Extensions.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3963,7 +3963,7 @@ public static partial class PartialSortExtension
{
/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey})"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// </summary>
/// <typeparam name="T">Type of elements in the sequence.</typeparam>
Expand All @@ -3980,7 +3980,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source, int coun

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, IComparer{TKey}, OrderByDirection)"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// An additional parameter specifies the direction of the sort
/// </summary>
Expand All @@ -4000,7 +4000,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source,

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation. An additional parameter specifies how the
/// elements compare to each other.
/// </summary>
Expand All @@ -4020,7 +4020,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source,

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, IComparer{TKey}, OrderByDirection)"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// Additional parameters specify how the elements compare to each other and
/// the direction of the sort.
Expand Down Expand Up @@ -4050,7 +4050,7 @@ public static partial class PartialSortByExtension

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
/// <typeparam name="TKey">Type of keys.</typeparam>
Expand All @@ -4070,7 +4070,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, OrderByDirection)"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// An additional parameter specifies the direction of the sort
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
Expand All @@ -4092,7 +4092,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// An additional parameter specifies how the keys compare to each other.
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
Expand All @@ -4115,7 +4115,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, OrderByDirection)"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// Additional parameters specify how the elements compare to each other and
/// the direction of the sort.
/// </summary>
Expand Down
6 changes: 3 additions & 3 deletions MoreLinq/MoreLinq.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>3.3.2</VersionPrefix>
<Authors>MoreLINQ Developers.</Authors>
<TargetFrameworks>net451;netstandard1.0;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net451;netstandard1.0;netstandard2.0;net6.0</TargetFrameworks>
<Nullable>enable</Nullable>
<!-- Parallel build is disabled to avoid file locking issues during T4 code generation.
See also: https://github.com/dotnet/msbuild/issues/2781 -->
Expand Down Expand Up @@ -188,12 +188,12 @@
<Reference Include="System" />
</ItemGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'net451' ">
<PropertyGroup>
<DefineConstants>$(DefineConstants);MORELINQ</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.0'">
<DefineConstants>$(DefineConstants);MORELINQ;NO_SERIALIZATION_ATTRIBUTES;NO_EXCEPTION_SERIALIZATION;NO_TRACING;NO_COM;NO_ASYNC</DefineConstants>
<DefineConstants>$(DefineConstants);NO_SERIALIZATION_ATTRIBUTES;NO_EXCEPTION_SERIALIZATION;NO_TRACING;NO_COM;NO_ASYNC</DefineConstants>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.0'">
Expand Down
16 changes: 8 additions & 8 deletions MoreLinq/PartialSort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static partial class MoreEnumerable
{
/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey})"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// </summary>
/// <typeparam name="T">Type of elements in the sequence.</typeparam>
Expand All @@ -44,7 +44,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source, int coun

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, IComparer{TKey}, OrderByDirection)"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// An additional parameter specifies the direction of the sort
/// </summary>
Expand All @@ -66,7 +66,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source,

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation. An additional parameter specifies how the
/// elements compare to each other.
/// </summary>
Expand All @@ -89,7 +89,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source,

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, IComparer{TKey}, OrderByDirection)"/>,
/// where each element is its key, and <see cref="Enumerable.Take{TSource}"/>
/// where each element is its key, and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/>
/// in a single operation.
/// Additional parameters specify how the elements compare to each other and
/// the direction of the sort.
Expand All @@ -116,7 +116,7 @@ public static IEnumerable<T> PartialSort<T>(this IEnumerable<T> source,

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
/// <typeparam name="TKey">Type of keys.</typeparam>
Expand All @@ -138,7 +138,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, OrderByDirection)"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// An additional parameter specifies the direction of the sort
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
Expand All @@ -162,7 +162,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="Enumerable.OrderBy{TSource,TKey}(IEnumerable{TSource},Func{TSource,TKey},IComparer{TKey})"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// An additional parameter specifies how the keys compare to each other.
/// </summary>
/// <typeparam name="TSource">Type of elements in the sequence.</typeparam>
Expand All @@ -189,7 +189,7 @@ public static IEnumerable<TSource> PartialSortBy<TSource, TKey>(

/// <summary>
/// Combines <see cref="MoreEnumerable.OrderBy{T, TKey}(IEnumerable{T}, Func{T, TKey}, OrderByDirection)"/>,
/// and <see cref="Enumerable.Take{TSource}"/> in a single operation.
/// and <see cref="Enumerable.Take{TSource}(IEnumerable{TSource},int)"/> in a single operation.
/// Additional parameters specify how the elements compare to each other and
/// the direction of the sort.
/// </summary>
Expand Down
12 changes: 7 additions & 5 deletions MoreLinq/Rank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ IEnumerable<int> _(IComparer<TKey> 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<TSource, int>(EqualityComparer<TSource>.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.
Expand Down
7 changes: 6 additions & 1 deletion MoreLinq/ReverseComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ public ReverseComparer(IComparer<T>? underlying)
_underlying = underlying ?? Comparer<T>.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;
Expand Down
5 changes: 2 additions & 3 deletions MoreLinq/ToDataTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down
7 changes: 3 additions & 4 deletions MoreLinq/Trace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ public static IEnumerable<TSource> Trace<TSource>(this IEnumerable<TSource> sour
{
if (source == null) throw new ArgumentNullException(nameof(source));

return TraceImpl(source,
string.IsNullOrEmpty(format)
? (Func<TSource, string>) (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));
}

/// <summary>
Expand Down