Skip to content

Commit 96a4f4b

Browse files
Merge pull request #25 from thomaslevesque/net60
Add .NET 6.0 TFM
2 parents 6d4f81a + 8895005 commit 96a4f4b

26 files changed

+405
-45
lines changed

Linq.Extras.sln

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.29424.173
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0179FA49-AFDB-429D-823D-F895E4C3393D}"
77
ProjectSection(SolutionItems) = preProject
@@ -10,7 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1010
build.cmd = build.cmd
1111
LICENSE.md = LICENSE.md
1212
README.md = README.md
13-
RELEASENOTES.md = RELEASENOTES.md
1413
EndProjectSection
1514
EndProject
1615
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Linq.Extras", "src\Linq.Extras\Linq.Extras.csproj", "{93E26A7D-E074-4B93-9B74-24414A12FB3B}"
@@ -23,7 +22,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{777D6312
2322
EndProject
2423
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "build", "tools\build\build.csproj", "{750F9598-6DAE-4036-B4D3-EFFA7A37FF74}"
2524
EndProject
26-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.Extras.Benchmarks", "tests\Linq.Extras.Benchmarks\Linq.Extras.Benchmarks.csproj", "{0FFABA2D-D2B5-48BF-B9A4-C4AA4A7D7C92}"
25+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Linq.Extras.Benchmarks", "tests\Linq.Extras.Benchmarks\Linq.Extras.Benchmarks.csproj", "{0FFABA2D-D2B5-48BF-B9A4-C4AA4A7D7C92}"
2726
EndProject
2827
Global
2928
GlobalSection(SolutionConfigurationPlatforms) = preSolution

Linq.Extras.sln.DotSettings

Lines changed: 0 additions & 3 deletions
This file was deleted.

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ branches:
44
- master
55
pull_requests:
66
do_not_increment_build_number: true
7-
image: Visual Studio 2019
7+
image: Visual Studio 2022
88
nuget:
99
disable_publish_on_pr: true
1010
build_script:

docs/Documentation.shfbproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<RootNamespace>Documentation</RootNamespace>
1515
<Name>Documentation</Name>
1616
<!-- SHFB properties -->
17-
<FrameworkVersion>Cross-platform (.NET Core/.NET Standard)</FrameworkVersion>
17+
<FrameworkVersion>.NET Core/.NET Standard/.NET 5.0+</FrameworkVersion>
1818
<OutputPath>api</OutputPath>
1919
<HtmlHelpName>Linq.Extras</HtmlHelpName>
2020
<Language>en-US</Language>

src/Linq.Extras/AppendPrepend.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using JetBrains.Annotations;
5+
using Linq.Extras.Internal;
6+
7+
namespace Linq.Extras
8+
{
9+
partial class XEnumerable
10+
{
11+
/// <summary>
12+
/// Appends the specified element to the specified sequence.
13+
/// </summary>
14+
/// <typeparam name="TSource">The type of the elements of <c>source</c>.</typeparam>
15+
/// <param name="source">The sequence to append an element to.</param>
16+
/// <param name="item">The element to append.</param>
17+
/// <returns>The source sequence followed by the appended element.</returns>
18+
/// <remarks>
19+
/// Linq already has this method in .NET Core, .NET Framework 4.7.1 and higher, and .NET Standard 1.6 and higher,
20+
/// so for these frameworks, the method is not marked as an extension method to avoid name conflicts.
21+
/// </remarks>
22+
#if !LACKS_APPEND_PREPEND
23+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.Append instead")]
24+
#endif
25+
[Pure]
26+
public static IEnumerable<TSource> Append<TSource>(
27+
#if !LACKS_APPEND_PREPEND
28+
[NotNull] IEnumerable<TSource> source,
29+
#else
30+
[NotNull] this IEnumerable<TSource> source,
31+
#endif
32+
TSource item)
33+
{
34+
source.CheckArgumentNull(nameof(source));
35+
return source.Concat(new[] { item });
36+
}
37+
38+
/// <summary>
39+
/// Prepends the specified element to the specified sequence.
40+
/// </summary>
41+
/// <typeparam name="TSource">The type of the elements of <c>source</c>.</typeparam>
42+
/// <param name="source">The sequence to prepend an element to.</param>
43+
/// <param name="item">The element to prepend.</param>
44+
/// <returns>The source sequence preceded by the prepended element.</returns>
45+
/// <remarks>
46+
/// Linq already has this method in .NET Core, .NET Framework 4.7.1 and higher, and .NET Standard 1.6 and higher,
47+
/// so it's not included in Linq.Extras for these frameworks.
48+
/// </remarks>
49+
#if !LACKS_APPEND_PREPEND
50+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.Prepend instead")]
51+
#endif
52+
[Pure]
53+
public static IEnumerable<TSource> Prepend<TSource>(
54+
#if !LACKS_APPEND_PREPEND
55+
[NotNull] IEnumerable<TSource> source,
56+
#else
57+
[NotNull] this IEnumerable<TSource> source,
58+
#endif
59+
TSource item)
60+
{
61+
source.CheckArgumentNull(nameof(source));
62+
return new[] { item }.Concat(source);
63+
}
64+
}
65+
}

src/Linq.Extras/Batch.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using JetBrains.Annotations;
34
using Linq.Extras.Internal;
45

@@ -13,6 +14,9 @@ partial class XEnumerable
1314
/// <param name="source">The sequence to split into batches.</param>
1415
/// <param name="size">The size of the batches</param>
1516
/// <returns>A sequence of batches of the specified size; the last batch can be shorter if there isn't enough elements remaining in the input sequence.</returns>
17+
#if FEATURE_CHUNK
18+
[Obsolete("This feature is now implemented in System.Linq. Please use Enumerable.Chunk instead")]
19+
#endif
1620
[Pure]
1721
public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
1822
[NotNull] this IEnumerable<TSource> source,

src/Linq.Extras/DistinctBy.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ partial class XEnumerable
1717
/// <param name="keySelector">A delegate that returns the key used to test equality between elements.</param>
1818
/// <param name="keyComparer">A comparer used to test equality between keys (can be null).</param>
1919
/// <returns>A sequence whose elements have distinct values for the specified key.</returns>
20+
#if FEATURE_BY_OPERATORS
21+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.DistinctBy instead")]
22+
#endif
2023
[Pure]
2124
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
25+
#if FEATURE_BY_OPERATORS
26+
[NotNull] IEnumerable<TSource> source,
27+
#else
2228
[NotNull] this IEnumerable<TSource> source,
29+
#endif
2330
[NotNull] Func<TSource, TKey> keySelector,
2431
IEqualityComparer<TKey>? keyComparer = null)
2532
{

src/Linq.Extras/Internal/MaybeNullAttribute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#if !FEATURE_NULLABILITY_ATTRIBUTES
1+
#if LACKS_NULLABILITY_ATTRIBUTES
2+
// ReSharper disable once CheckNamespace
23
namespace System.Diagnostics.CodeAnalysis
34
{
45
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>

src/Linq.Extras/Linq.Extras.csproj

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project Sdk="Microsoft.NET.Sdk">
33

44
<PropertyGroup>
5-
<TargetFrameworks>netstandard2.0;netstandard2.1;net45;netcoreapp3.1;net5.0</TargetFrameworks>
5+
<TargetFrameworks>netstandard2.0;netstandard2.1;net45;net471;net472;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
66
<Description>A set of helper and extension methods to complement the System.Linq namespace.</Description>
77
<Authors>Thomas Levesque</Authors>
88
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
@@ -20,20 +20,40 @@
2020
</PropertyGroup>
2121

2222
<ItemGroup>
23-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
24-
<PackageReference Include="MinVer" Version="2.3.0" PrivateAssets="All" />
23+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
24+
<PackageReference Include="MinVer" Version="2.5.0" PrivateAssets="All" />
2525
</ItemGroup>
2626

27+
<PropertyGroup Condition="'$(TargetFramework)' == 'net45'">
28+
<DefineConstants>$(DefineConstants);LACKS_APPEND_PREPEND;LACKS_TO_HASHSET;LACKS_NULLABILITY_ATTRIBUTES;LACKS_COMPARER_NULLABILITY</DefineConstants>
29+
</PropertyGroup>
30+
31+
<PropertyGroup Condition="'$(TargetFramework)' == 'net471'">
32+
<DefineConstants>$(DefineConstants);LACKS_TO_HASHSET;LACKS_NULLABILITY_ATTRIBUTES;LACKS_COMPARER_NULLABILITY</DefineConstants>
33+
</PropertyGroup>
34+
35+
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
36+
<DefineConstants>$(DefineConstants);LACKS_NULLABILITY_ATTRIBUTES;LACKS_COMPARER_NULLABILITY</DefineConstants>
37+
</PropertyGroup>
38+
39+
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
40+
<DefineConstants>$(DefineConstants);LACKS_NULLABILITY_ATTRIBUTES;LACKS_COMPARER_NULLABILITY</DefineConstants>
41+
</PropertyGroup>
42+
2743
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
28-
<DefineConstants>$(DefineConstants);FEATURE_NULLABILITY_ATTRIBUTES</DefineConstants>
44+
<DefineConstants>$(DefineConstants);LACKS_COMPARER_NULLABILITY</DefineConstants>
2945
</PropertyGroup>
3046

3147
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
32-
<DefineConstants>$(DefineConstants);FEATURE_NULLABILITY_ATTRIBUTES;FEATURE_COMPARER_NULLABILITY</DefineConstants>
48+
<DefineConstants>$(DefineConstants)</DefineConstants>
3349
</PropertyGroup>
3450

3551
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0'">
36-
<DefineConstants>$(DefineConstants);FEATURE_NULLABILITY_ATTRIBUTES;FEATURE_COMPARER_NULLABILITY</DefineConstants>
52+
<DefineConstants>$(DefineConstants)</DefineConstants>
53+
</PropertyGroup>
54+
55+
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
56+
<DefineConstants>$(DefineConstants);FEATURE_BY_OPERATORS;FEATURE_MINMAX_COMPARER;FEATURE_ORDEFAULT_OVERLOADS;FEATURE_CHUNK</DefineConstants>
3757
</PropertyGroup>
3858

3959
</Project>

src/Linq.Extras/MinMax.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@ partial class XEnumerable
2323
/// If <c>TSource</c> is a reference type or nullable value type, and the sequence is empty, the method will return <c>null</c>.
2424
/// If <c>TSource</c> is a value type, and the sequence is empty, the method will throw an <see cref="InvalidOperationException"/>.
2525
/// </remarks>
26+
#if FEATURE_MINMAX_COMPARER
27+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.Max instead")]
28+
#endif
2629
[Pure]
2730
[return: MaybeNull]
2831
public static TSource Max<TSource>(
32+
#if FEATURE_MINMAX_COMPARER
33+
[NotNull] IEnumerable<TSource> source,
34+
#else
2935
[NotNull] this IEnumerable<TSource> source,
36+
#endif
3037
[NotNull] IComparer<TSource> comparer)
3138
{
3239
source.CheckArgumentNull(nameof(source));
@@ -47,10 +54,17 @@ public static TSource Max<TSource>(
4754
/// If <c>TSource</c> is a reference type or nullable value type, and the sequence is empty, the method will return <c>null</c>.
4855
/// If <c>TSource</c> is a value type, and the sequence is empty, the method will throw an <see cref="InvalidOperationException"/>.
4956
/// </remarks>
57+
#if FEATURE_MINMAX_COMPARER
58+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.Min instead")]
59+
#endif
5060
[Pure]
5161
[return: MaybeNull]
5262
public static TSource Min<TSource>(
63+
#if FEATURE_MINMAX_COMPARER
64+
[NotNull] IEnumerable<TSource> source,
65+
#else
5366
[NotNull] this IEnumerable<TSource> source,
67+
#endif
5468
[NotNull] IComparer<TSource> comparer)
5569
{
5670
source.CheckArgumentNull(nameof(source));
@@ -137,10 +151,17 @@ private static InvalidOperationException EmptySequenceException()
137151
/// If <c>TKey</c> is a reference type or nullable value type, and the sequence is empty, the method will return <c>null</c>.
138152
/// If <c>TKey</c> is a value type, and the sequence is empty, the method will throw an <see cref="InvalidOperationException"/>.
139153
/// </remarks>
154+
#if FEATURE_BY_OPERATORS
155+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.MaxBy instead")]
156+
#endif
140157
[Pure]
141158
[return: MaybeNull]
142159
public static TSource MaxBy<TSource, TKey>(
160+
#if FEATURE_BY_OPERATORS
161+
[NotNull] IEnumerable<TSource> source,
162+
#else
143163
[NotNull] this IEnumerable<TSource> source,
164+
#endif
144165
[NotNull] Func<TSource, TKey> keySelector,
145166
IComparer<TKey>? keyComparer = null)
146167
{
@@ -164,10 +185,17 @@ public static TSource MaxBy<TSource, TKey>(
164185
/// If <c>TKey</c> is a reference type or nullable value type, and the sequence is empty, the method will return <c>null</c>.
165186
/// If <c>TKey</c> is a value type, and the sequence is empty, the method will throw an <see cref="InvalidOperationException"/>.
166187
/// </remarks>
188+
#if FEATURE_BY_OPERATORS
189+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.MinBy instead")]
190+
#endif
167191
[Pure]
168192
[return: MaybeNull]
169193
public static TSource MinBy<TSource, TKey>(
194+
#if FEATURE_BY_OPERATORS
195+
[NotNull] IEnumerable<TSource> source,
196+
#else
170197
[NotNull] this IEnumerable<TSource> source,
198+
#endif
171199
[NotNull] Func<TSource, TKey> keySelector,
172200
IComparer<TKey>? keyComparer = null)
173201
{

src/Linq.Extras/OrDefault.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,25 @@ namespace Linq.Extras
99
{
1010
partial class XEnumerable
1111
{
12+
// TODO: exists in .NET 6
13+
1214
/// <summary>
1315
/// Returns the first element of a sequence or the specified default value if the sequence contains no elements.
1416
/// </summary>
1517
/// <typeparam name="TSource">The type of the elements of <c>source</c>.</typeparam>
1618
/// <param name="source">The sequence to return the first element of.</param>
1719
/// <param name="defaultValue">The default value to return if the sequence is empty.</param>
1820
/// <returns><c>defaultValue</c> if <c>source</c> is empty; otherwise, the first element in <c>source</c>.</returns>
21+
#if FEATURE_ORDEFAULT_OVERLOADS
22+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.FirstOrDefault instead")]
23+
#endif
1924
[Pure]
2025
public static TSource FirstOrDefault<TSource>(
26+
#if FEATURE_ORDEFAULT_OVERLOADS
27+
[NotNull] IEnumerable<TSource> source,
28+
#else
2129
[NotNull] this IEnumerable<TSource> source,
30+
#endif
2231
TSource defaultValue)
2332
{
2433
source.CheckArgumentNull(nameof(source));
@@ -33,9 +42,16 @@ public static TSource FirstOrDefault<TSource>(
3342
/// <param name="predicate">A function to test each element for a condition.</param>
3443
/// <param name="defaultValue">The default value to return if no matching element is found.</param>
3544
/// <returns><c>defaultValue</c> if source is empty or if no element passes the test specified by <c>predicate</c>; otherwise, the first element in <c>source</c> that passes the test specified by <c>predicate</c>.</returns>
45+
#if FEATURE_ORDEFAULT_OVERLOADS
46+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.FirstOrDefault instead")]
47+
#endif
3648
[Pure]
3749
public static TSource FirstOrDefault<TSource>(
50+
#if FEATURE_ORDEFAULT_OVERLOADS
51+
[NotNull] IEnumerable<TSource> source,
52+
#else
3853
[NotNull] this IEnumerable<TSource> source,
54+
#endif
3955
[NotNull] Func<TSource, bool> predicate,
4056
TSource defaultValue)
4157
{
@@ -51,9 +67,16 @@ public static TSource FirstOrDefault<TSource>(
5167
/// <param name="source">The sequence to return the last element of.</param>
5268
/// <param name="defaultValue">The default value to return if the sequence is empty.</param>
5369
/// <returns><c>defaultValue</c> if <c>source</c> is empty; otherwise, the last element in <c>source</c>.</returns>
70+
#if FEATURE_ORDEFAULT_OVERLOADS
71+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.LastOrDefault instead")]
72+
#endif
5473
[Pure]
5574
public static TSource LastOrDefault<TSource>(
75+
#if FEATURE_ORDEFAULT_OVERLOADS
76+
[NotNull] IEnumerable<TSource> source,
77+
#else
5678
[NotNull] this IEnumerable<TSource> source,
79+
#endif
5780
[NotNull] TSource defaultValue)
5881
{
5982
source.CheckArgumentNull(nameof(source));
@@ -68,9 +91,16 @@ public static TSource LastOrDefault<TSource>(
6891
/// <param name="predicate">A function to test each element for a condition.</param>
6992
/// <param name="defaultValue">The default value to return if no matching element is found.</param>
7093
/// <returns><c>defaultValue</c> if source is empty or if no element passes the test specified by <c>predicate</c>; otherwise, the last element in <c>source</c> that passes the test specified by <c>predicate</c>.</returns>
94+
#if FEATURE_ORDEFAULT_OVERLOADS
95+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.LastOrDefault instead")]
96+
#endif
7197
[Pure]
7298
public static TSource LastOrDefault<TSource>(
99+
#if FEATURE_ORDEFAULT_OVERLOADS
100+
[NotNull] IEnumerable<TSource> source,
101+
#else
73102
[NotNull] this IEnumerable<TSource> source,
103+
#endif
74104
[NotNull] Func<TSource, bool> predicate,
75105
TSource defaultValue)
76106
{
@@ -107,9 +137,16 @@ public static TSource ElementAtOrDefault<TSource>(
107137
/// <param name="source">The sequence to return the single element of.</param>
108138
/// <param name="defaultValue">The default value to return if the sequence is empty.</param>
109139
/// <returns>The single element of the input sequence, or <c>defaultValue</c> if the sequence contains no elements.</returns>
140+
#if FEATURE_ORDEFAULT_OVERLOADS
141+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.SingleOrDefault instead")]
142+
#endif
110143
[Pure]
111144
public static TSource SingleOrDefault<TSource>(
145+
#if FEATURE_ORDEFAULT_OVERLOADS
146+
[NotNull] IEnumerable<TSource> source,
147+
#else
112148
[NotNull] this IEnumerable<TSource> source,
149+
#endif
113150
TSource defaultValue)
114151
{
115152
source.CheckArgumentNull(nameof(source));
@@ -138,9 +175,16 @@ public static TSource SingleOrDefault<TSource>(
138175
/// <param name="predicate">A function to test an element for a condition.</param>
139176
/// <param name="defaultValue">The default value to return if the no element matches the predicate.</param>
140177
/// <returns>The single element of the input sequence that satisfies the condition, or <c>defaultValue</c> if no such element is found.</returns>
178+
#if FEATURE_ORDEFAULT_OVERLOADS
179+
[Obsolete("This feature is now implemented directly in System.Linq. Please use Enumerable.SingleOrDefault instead")]
180+
#endif
141181
[Pure]
142182
public static TSource SingleOrDefault<TSource>(
183+
#if FEATURE_ORDEFAULT_OVERLOADS
184+
[NotNull] IEnumerable<TSource> source,
185+
#else
143186
[NotNull] this IEnumerable<TSource> source,
187+
#endif
144188
[NotNull] Func<TSource, bool> predicate,
145189
TSource defaultValue)
146190
{

0 commit comments

Comments
 (0)