From 022149fd084b5f9af4c3f36a8547cdf169ef4cbe Mon Sep 17 00:00:00 2001 From: Thomas Bruderer Date: Thu, 12 Feb 2026 10:04:09 +0100 Subject: [PATCH 1/5] Compile Funcky in .NET10 * prepare Framework Feature Constants * Fixes #867 (System.Linq.Shuffle) * Fixes duplicate import of System.Linq.Async --- FrameworkFeatureConstants.props | 3 +++ .../Funcky.Analyzers.Test/Funcky.Analyzers.Test.csproj | 2 +- Funcky.Async.Test/Funcky.Async.Test.csproj | 2 +- .../Extensions/AsyncEnumerableExtensions/Shuffle.cs | 2 ++ Funcky.Async/Funcky.Async.csproj | 6 +++--- .../Funcky.SourceGenerator.Test.csproj | 2 +- Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs | 2 +- Funcky.Test/Funcky.Test.csproj | 2 +- Funcky.Xunit.Test/Funcky.Xunit.Test.csproj | 2 +- Funcky.Xunit.v3.Test/Funcky.Xunit.v3.Test.csproj | 2 +- Funcky/Extensions/EnumerableExtensions/Shuffle.cs | 4 +++- Funcky/Funcky.csproj | 4 ++-- global.json | 2 +- 13 files changed, 21 insertions(+), 14 deletions(-) diff --git a/FrameworkFeatureConstants.props b/FrameworkFeatureConstants.props index 6912a671..961605d7 100644 --- a/FrameworkFeatureConstants.props +++ b/FrameworkFeatureConstants.props @@ -21,4 +21,7 @@ $(DefineConstants);REFLECTION_ASSEMBLY_NAME_INFO;REFLECTION_TYPE_NAME;ORDERED_DICTIONARY + + $(DefineConstants);SHUFFLE_EXTENSION + diff --git a/Funcky.Analyzers/Funcky.Analyzers.Test/Funcky.Analyzers.Test.csproj b/Funcky.Analyzers/Funcky.Analyzers.Test/Funcky.Analyzers.Test.csproj index 069027b9..c7aa8f6e 100644 --- a/Funcky.Analyzers/Funcky.Analyzers.Test/Funcky.Analyzers.Test.csproj +++ b/Funcky.Analyzers/Funcky.Analyzers.Test/Funcky.Analyzers.Test.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 true true diff --git a/Funcky.Async.Test/Funcky.Async.Test.csproj b/Funcky.Async.Test/Funcky.Async.Test.csproj index d956a47e..a4ea6c3f 100644 --- a/Funcky.Async.Test/Funcky.Async.Test.csproj +++ b/Funcky.Async.Test/Funcky.Async.Test.csproj @@ -1,6 +1,6 @@ - net9.0;net8.0;net7.0 + net10.0;net9.0;net8.0;net7.0 preview enable false diff --git a/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs b/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs index 62a02ea4..58783f14 100644 --- a/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs +++ b/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs @@ -1,3 +1,4 @@ +#if SHUFFLE_EXTENSION #if !RANDOM_SHUFFLE using Funcky.Internal; #endif @@ -27,3 +28,4 @@ public static async ValueTask> ShuffleAsync(this => (await source.ToListAsync(cancellationToken).ConfigureAwait(false)).ToRandomList(random); #endif } +#endif diff --git a/Funcky.Async/Funcky.Async.csproj b/Funcky.Async/Funcky.Async.csproj index 48f8169c..ba76a8c9 100644 --- a/Funcky.Async/Funcky.Async.csproj +++ b/Funcky.Async/Funcky.Async.csproj @@ -1,7 +1,7 @@ - net9.0 - $(FunckyNewestTargetFramework);net8.0;net5.0;netstandard2.1;netstandard2.0 + net10.0 + $(FunckyNewestTargetFramework);net9.0;net8.0;net5.0;netstandard2.1;netstandard2.0 preview enable Extends Funcky with support for IAsyncEnumerable and Tasks. @@ -46,7 +46,7 @@ - + diff --git a/Funcky.SourceGenerator.Test/Funcky.SourceGenerator.Test.csproj b/Funcky.SourceGenerator.Test/Funcky.SourceGenerator.Test.csproj index b50fdf5a..6eec7683 100644 --- a/Funcky.SourceGenerator.Test/Funcky.SourceGenerator.Test.csproj +++ b/Funcky.SourceGenerator.Test/Funcky.SourceGenerator.Test.csproj @@ -3,7 +3,7 @@ Funcky.SourceGenerator.Test Funcky.SourceGenerator.Test - net9.0 + net10.0 enable enable preview diff --git a/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs b/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs index 43f96f46..9070f0cc 100644 --- a/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs @@ -33,6 +33,6 @@ public Property AShuffleHasTheSameElementsAsTheSource(List source) [Property] public Property AShuffleHasTheSameLengthAsTheSource(List source) - => (source.Shuffle().Count == source.Count) + => (source.Shuffle().Count() == source.Count) .ToProperty(); } diff --git a/Funcky.Test/Funcky.Test.csproj b/Funcky.Test/Funcky.Test.csproj index 4a49af35..7759a253 100644 --- a/Funcky.Test/Funcky.Test.csproj +++ b/Funcky.Test/Funcky.Test.csproj @@ -1,6 +1,6 @@ - net9.0;net8.0;net7.0;net6.0 + net10.0;net9.0;net8.0;net7.0;net6.0 $(TargetFrameworks);net4.8 preview enable diff --git a/Funcky.Xunit.Test/Funcky.Xunit.Test.csproj b/Funcky.Xunit.Test/Funcky.Xunit.Test.csproj index e23fb008..e6a9f8c6 100644 --- a/Funcky.Xunit.Test/Funcky.Xunit.Test.csproj +++ b/Funcky.Xunit.Test/Funcky.Xunit.Test.csproj @@ -1,6 +1,6 @@ - net9.0 + net10.0 preview enable false diff --git a/Funcky.Xunit.v3.Test/Funcky.Xunit.v3.Test.csproj b/Funcky.Xunit.v3.Test/Funcky.Xunit.v3.Test.csproj index d2e42bb3..04046877 100644 --- a/Funcky.Xunit.v3.Test/Funcky.Xunit.v3.Test.csproj +++ b/Funcky.Xunit.v3.Test/Funcky.Xunit.v3.Test.csproj @@ -1,6 +1,6 @@ - net9.0 + net10.0 preview enable false diff --git a/Funcky/Extensions/EnumerableExtensions/Shuffle.cs b/Funcky/Extensions/EnumerableExtensions/Shuffle.cs index 5d6c9d0c..f2abb4b8 100644 --- a/Funcky/Extensions/EnumerableExtensions/Shuffle.cs +++ b/Funcky/Extensions/EnumerableExtensions/Shuffle.cs @@ -6,6 +6,7 @@ namespace Funcky.Extensions; public static partial class EnumerableExtensions { +#if !SHUFFLE_EXTENSION /// /// Returns the given sequence eagerly in random Order in O(n). /// @@ -14,6 +15,7 @@ public static partial class EnumerableExtensions [Pure] public static IReadOnlyList Shuffle(this IEnumerable source) => source.Shuffle(new Random()); +#endif /// /// Returns the given sequence eagerly in random Order in O(n). @@ -32,5 +34,5 @@ public static IReadOnlyList Shuffle(this IEnumerable => source .ToList() .ToRandomList(random); - #endif +#endif } diff --git a/Funcky/Funcky.csproj b/Funcky/Funcky.csproj index 56aad6bb..30e59407 100644 --- a/Funcky/Funcky.csproj +++ b/Funcky/Funcky.csproj @@ -1,7 +1,7 @@  - net9.0 - $(FunckyNewestTargetFramework);net8.0;net7.0;net6.0;net5.0;netcoreapp3.1;netstandard2.0;netstandard2.1 + net10.0 + $(FunckyNewestTargetFramework);net9.0;net8.0;net7.0;net6.0;net5.0;netcoreapp3.1;netstandard2.0;netstandard2.1 preview enable Funcky diff --git a/global.json b/global.json index fe402e1f..311edc21 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.200", + "version": "10.0.103", "rollForward": "feature" } } From 1fa2d79c285968e39ea13b66aec569d733174f7a Mon Sep 17 00:00:00 2001 From: Thomas Bruderer Date: Thu, 12 Feb 2026 11:07:31 +0100 Subject: [PATCH 2/5] Async remains at .NET9 * The .NET 10 code needs to be adapted when moved --- FrameworkFeatureConstants.props | 2 +- .../AsyncEnumerableExtensions/AdjacentGroupByTest.cs | 2 +- Funcky.Async.Test/Funcky.Async.Test.csproj | 4 ++-- Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs | 2 -- Funcky.Async/Funcky.Async.csproj | 4 ++-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/FrameworkFeatureConstants.props b/FrameworkFeatureConstants.props index 961605d7..b7e712b1 100644 --- a/FrameworkFeatureConstants.props +++ b/FrameworkFeatureConstants.props @@ -22,6 +22,6 @@ $(DefineConstants);REFLECTION_ASSEMBLY_NAME_INFO;REFLECTION_TYPE_NAME;ORDERED_DICTIONARY - $(DefineConstants);SHUFFLE_EXTENSION + $(DefineConstants);SHUFFLE_EXTENSION;INTEGRATED_ASYNC diff --git a/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs b/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs index 5ab69b53..6d399a69 100644 --- a/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs +++ b/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs @@ -29,7 +29,7 @@ public void AdjacentGroupByIsEnumeratedLazily() public async Task GivenAnEmptySequenceAnyKeySelectorReturnsAnEmptySequence() { var empty = AsyncEnumerable.Empty(); - + await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.Month)); await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.DayOfYear / 7)); await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.Year)); diff --git a/Funcky.Async.Test/Funcky.Async.Test.csproj b/Funcky.Async.Test/Funcky.Async.Test.csproj index a4ea6c3f..d02c4547 100644 --- a/Funcky.Async.Test/Funcky.Async.Test.csproj +++ b/Funcky.Async.Test/Funcky.Async.Test.csproj @@ -1,6 +1,6 @@ - + - net10.0;net9.0;net8.0;net7.0 + net9.0;net8.0;net7.0 preview enable false diff --git a/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs b/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs index 58783f14..62a02ea4 100644 --- a/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs +++ b/Funcky.Async/Extensions/AsyncEnumerableExtensions/Shuffle.cs @@ -1,4 +1,3 @@ -#if SHUFFLE_EXTENSION #if !RANDOM_SHUFFLE using Funcky.Internal; #endif @@ -28,4 +27,3 @@ public static async ValueTask> ShuffleAsync(this => (await source.ToListAsync(cancellationToken).ConfigureAwait(false)).ToRandomList(random); #endif } -#endif diff --git a/Funcky.Async/Funcky.Async.csproj b/Funcky.Async/Funcky.Async.csproj index ba76a8c9..69d04de6 100644 --- a/Funcky.Async/Funcky.Async.csproj +++ b/Funcky.Async/Funcky.Async.csproj @@ -1,7 +1,7 @@ - net10.0 - $(FunckyNewestTargetFramework);net9.0;net8.0;net5.0;netstandard2.1;netstandard2.0 + net9.0 + $(FunckyNewestTargetFramework);net8.0;net5.0;netstandard2.1;netstandard2.0 preview enable Extends Funcky with support for IAsyncEnumerable and Tasks. From 73bc76e6ecdf26bf8ae8bfb192c16df88a27692e Mon Sep 17 00:00:00 2001 From: Thomas Bruderer Date: Thu, 12 Feb 2026 11:44:08 +0100 Subject: [PATCH 3/5] Fix warnings * unwanted spaces * Add public API overloads from new API (ReadOnlySpan) --- .../AsyncEnumerableExtensions/AdjacentGroupByTest.cs | 2 +- Funcky/PublicAPI.Shipped.txt | 1 - Funcky/PublicAPI.Unshipped.txt | 5 +++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs b/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs index 6d399a69..5ab69b53 100644 --- a/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs +++ b/Funcky.Async.Test/Extensions/AsyncEnumerableExtensions/AdjacentGroupByTest.cs @@ -29,7 +29,7 @@ public void AdjacentGroupByIsEnumeratedLazily() public async Task GivenAnEmptySequenceAnyKeySelectorReturnsAnEmptySequence() { var empty = AsyncEnumerable.Empty(); - + await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.Month)); await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.DayOfYear / 7)); await AsyncAssert.Empty(empty.AdjacentGroupBy(date => date.Year)); diff --git a/Funcky/PublicAPI.Shipped.txt b/Funcky/PublicAPI.Shipped.txt index c7b1e8bc..1bd77081 100644 --- a/Funcky/PublicAPI.Shipped.txt +++ b/Funcky/PublicAPI.Shipped.txt @@ -314,7 +314,6 @@ static Funcky.Extensions.EnumerableExtensions.Sequence(this Syst static Funcky.Extensions.EnumerableExtensions.Sequence(this System.Collections.Generic.IEnumerable>! source) -> Funcky.Monads.Option!> static Funcky.Extensions.EnumerableExtensions.Sequence(this System.Collections.Generic.IEnumerable>! source) -> Funcky.Monads.Result!> static Funcky.Extensions.EnumerableExtensions.Sequence(this System.Collections.Generic.IEnumerable!>! sequence) -> System.Lazy!>! -static Funcky.Extensions.EnumerableExtensions.Shuffle(this System.Collections.Generic.IEnumerable! source) -> System.Collections.Generic.IReadOnlyList! static Funcky.Extensions.EnumerableExtensions.Shuffle(this System.Collections.Generic.IEnumerable! source, System.Random! random) -> System.Collections.Generic.IReadOnlyList! static Funcky.Extensions.EnumerableExtensions.SingleOrNone(this System.Collections.Generic.IEnumerable! source) -> Funcky.Monads.Option static Funcky.Extensions.EnumerableExtensions.SingleOrNone(this System.Collections.Generic.IEnumerable! source, System.Func! predicate) -> Funcky.Monads.Option diff --git a/Funcky/PublicAPI.Unshipped.txt b/Funcky/PublicAPI.Unshipped.txt index 52871fca..f1a723c2 100644 --- a/Funcky/PublicAPI.Unshipped.txt +++ b/Funcky/PublicAPI.Unshipped.txt @@ -70,8 +70,13 @@ static Funcky.Extensions.ListExtensions.LastIndexOfOrNone(this System.Col static Funcky.Extensions.ListExtensions.LastIndexOfOrNone(this System.Collections.Immutable.IImmutableList! list, TItem item, int startIndex, int count, System.Collections.Generic.IEqualityComparer? equalityComparer) -> Funcky.Monads.Option static Funcky.Extensions.ListExtensions.LastIndexOfOrNone(this System.Collections.Immutable.IImmutableList! list, TItem item, System.Collections.Generic.IEqualityComparer? equalityComparer) -> Funcky.Monads.Option static Funcky.Extensions.OrderedDictionaryExtensions.IndexOfOrNone(this System.Collections.Generic.OrderedDictionary! dictionary, TKey key) -> Funcky.Monads.Option +static Funcky.Extensions.ParseExtensions.ParseGuidOrNone(this System.ReadOnlySpan candidate) -> Funcky.Monads.Option +static Funcky.Extensions.ParseExtensions.ParseGuidOrNone(this System.ReadOnlySpan candidate, System.IFormatProvider? provider) -> Funcky.Monads.Option +static Funcky.Extensions.ParseExtensions.ParseIPAddressOrNone(this System.ReadOnlySpan candidate) -> Funcky.Monads.Option static Funcky.Extensions.ParseExtensions.ParseIPNetworkOrNone(this string? candidate) -> Funcky.Monads.Option +static Funcky.Extensions.ParseExtensions.ParseIPNetworkOrNone(this System.ReadOnlySpan candidate) -> Funcky.Monads.Option static Funcky.Extensions.ParseExtensions.ParseIPNetworkOrNone(this System.ReadOnlySpan candidate) -> Funcky.Monads.Option +static Funcky.Extensions.ParseExtensions.ParseVersionOrNone(this System.ReadOnlySpan candidate) -> Funcky.Monads.Option static Funcky.Functional.Apply(System.Func! func, Funcky.Unit p1, Funcky.Unit p2, Funcky.Unit p3, Funcky.Unit p4, T5 p5) -> System.Func! static Funcky.Functional.Apply(System.Func! func, Funcky.Unit p1, Funcky.Unit p2, Funcky.Unit p3, T4 p4, Funcky.Unit p5) -> System.Func! static Funcky.Functional.Apply(System.Func! func, Funcky.Unit p1, Funcky.Unit p2, Funcky.Unit p3, T4 p4, T5 p5) -> System.Func! From 92847e500914b2c2bd84305d8b0f20fc091eb5b4 Mon Sep 17 00:00:00 2001 From: Thomas Bruderer Date: Thu, 12 Feb 2026 11:52:36 +0100 Subject: [PATCH 4/5] Add suppression for Shuffle (is now in the framework) --- Funcky/CompatibilitySuppressions.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Funcky/CompatibilitySuppressions.xml b/Funcky/CompatibilitySuppressions.xml index 46401cc6..da67a718 100644 --- a/Funcky/CompatibilitySuppressions.xml +++ b/Funcky/CompatibilitySuppressions.xml @@ -7,6 +7,12 @@ lib/net5.0/Funcky.dll lib/net6.0/Funcky.dll + + CP0002 + M:Funcky.Extensions.EnumerableExtensions.Shuffle``1(System.Collections.Generic.IEnumerable{``0}) + lib/net9.0/Funcky.dll + lib/net10.0/Funcky.dll + CP0021 M:Funcky.Extensions.DictionaryExtensions.GetValueOrNone``2(System.Collections.Generic.IDictionary{``0,``1},``0)``0:notnull From 974a9f92331bf6daf35a948687dd320fa7719f64 Mon Sep 17 00:00:00 2001 From: Thomas Bruderer Date: Thu, 12 Feb 2026 11:58:37 +0100 Subject: [PATCH 5/5] Fix test - the framework seems to implment it in a lazy way --- Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs b/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs index 9070f0cc..fe9ccc91 100644 --- a/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/ShuffleTest.cs @@ -1,13 +1,16 @@ using FsCheck; using FsCheck.Fluent; using FsCheck.Xunit; +#if !SHUFFLE_EXTENSION using Funcky.Test.TestUtils; using Xunit.Sdk; +#endif namespace Funcky.Test.Extensions.EnumerableExtensions; public sealed class ShuffleTest { +#if !SHUFFLE_EXTENSION [Fact] public void AShuffleIsEnumeratedEagerly() { @@ -15,13 +18,14 @@ public void AShuffleIsEnumeratedEagerly() Assert.Throws(() => doNotEnumerate.Shuffle()); } +#endif [Fact] public void AShuffleWithASpecificRandomDistributionAlwaysReturnsTheSameShuffle() { var source = Enumerable.Range(0, 16); - Assert.Equal(Sequence.Return(3, 2, 6, 15, 14, 0, 5, 8, 11, 7, 9, 12, 1, 13, 10, 4), source.Shuffle(new System.Random(1337))); + Assert.Equal(Sequence.Return(3, 2, 6, 15, 14, 0, 5, 8, 11, 7, 9, 12, 1, 13, 10, 4), source.Shuffle(new Random(1337))); } [Property]