diff --git a/Funcky.Test/Extensions/EnumerableExtensions/AnyOrElseTest.cs b/Funcky.Test/Extensions/EnumerableExtensions/AnyOrElseTest.cs index a2e2ff9e..53d1c71a 100644 --- a/Funcky.Test/Extensions/EnumerableExtensions/AnyOrElseTest.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/AnyOrElseTest.cs @@ -13,7 +13,7 @@ public void IsEmptyWhenBothEnumerablesAreEmpty() [Fact] public void IsSourceEnumerableWhenNonEmpty() { - var source = Sequence.Return(1, 2, 3).EraseNonEnumeratedCount(); + var source = Sequence.Return(1, 2, 3).PreventLinqOptimizations(); var fallback = Sequence.Return(4, 5, 6); Assert.Equal(source, source.AnyOrElse(fallback)); } @@ -21,7 +21,7 @@ public void IsSourceEnumerableWhenNonEmpty() [Fact] public void IsFallbackEnumerableWhenSourceIsEmpty() { - var source = Enumerable.Empty().EraseNonEnumeratedCount(); + var source = Enumerable.Empty().PreventLinqOptimizations(); var fallback = Sequence.Return(1, 2, 3); Assert.Equal(fallback, source.AnyOrElse(fallback)); } @@ -36,7 +36,7 @@ public void SourceIsEnumeratedLazily() [Fact] public void FallbackIsEnumeratedLazily() { - var source = Enumerable.Empty().EraseNonEnumeratedCount(); + var source = Enumerable.Empty().PreventLinqOptimizations(); _ = source.AnyOrElse(new FailOnEnumerationSequence()); } diff --git a/Funcky.Test/Extensions/EnumerableExtensions/GetNonEnumeratedCountOrNoneTest.cs b/Funcky.Test/Extensions/EnumerableExtensions/GetNonEnumeratedCountOrNoneTest.cs index 54bef9df..2b6e1097 100644 --- a/Funcky.Test/Extensions/EnumerableExtensions/GetNonEnumeratedCountOrNoneTest.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/GetNonEnumeratedCountOrNoneTest.cs @@ -28,7 +28,7 @@ public void GetNonEnumeratedCountOrNoneReturnsCountOnEnumerableRange() [Property] public Property GetNonEnumeratedCountOrNoneReturnsNoneForInstancesWithoutCount(List list) { - return list.EraseNonEnumeratedCount().GetNonEnumeratedCountOrNone() + return list.PreventLinqOptimizations().GetNonEnumeratedCountOrNone() .Match(none: true, some: False) .ToProperty(); } diff --git a/Funcky.Test/Extensions/EnumerableExtensions/MaterializeTest.cs b/Funcky.Test/Extensions/EnumerableExtensions/MaterializeTest.cs index 5b9fcd73..1135d1bc 100644 --- a/Funcky.Test/Extensions/EnumerableExtensions/MaterializeTest.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/MaterializeTest.cs @@ -26,7 +26,7 @@ public void MaterializeDoesNotEnumerateCollectionTypes() [Fact] public void MaterializeReturnsImmutableCollectionWhenEnumerated() { - var sequence = Enumerable.Repeat("Hello world!", 3); + var sequence = Enumerable.Repeat("Hello world!", 3).PreventLinqOptimizations(); Assert.IsType>(sequence.Materialize()); } @@ -34,11 +34,22 @@ public void MaterializeReturnsImmutableCollectionWhenEnumerated() [Fact] public void MaterializeWithMaterializationReturnsCorrectCollectionWhenEnumerate() { - var sequence = Enumerable.Repeat("Hello world!", 3); + var sequence = Enumerable.Repeat("Hello world!", 3).PreventLinqOptimizations(); Assert.IsType>(sequence.Materialize(ToHashSet)); } +#if NET8_0_OR_GREATER + // This is an optimization added in .NET 8 + [Fact] + public void MaterializeDoesNotEnumerableEnumerableReturnedByRepeat() + { + var sequence = Enumerable.Repeat("Hello world!", 3); + var materialized = sequence.Materialize>(_ => throw new FailException("Materialization should never be called")); + Assert.Same(sequence, materialized); + } +#endif + [Fact] public void MaterializeDoesNotEnumerateCollectionWhichImplementsICollectionOnly() { diff --git a/Funcky.Test/TestUtils/EnumerableExtensions.cs b/Funcky.Test/TestUtils/EnumerableExtensions.cs index 97873c08..33b78295 100644 --- a/Funcky.Test/TestUtils/EnumerableExtensions.cs +++ b/Funcky.Test/TestUtils/EnumerableExtensions.cs @@ -2,10 +2,9 @@ namespace Funcky.Test.TestUtils; internal static class EnumerableExtensions { - internal static IEnumerable EraseNonEnumeratedCount(this IEnumerable source) + /// Prevents LINQ from optimizing by hiding the underlying source enumerable. + internal static IEnumerable PreventLinqOptimizations(this IEnumerable source) { - // Having our own state machine erases the non enumerated count - // provided when using LINQ methods such as Select. foreach (var element in source) { yield return element;