From e09ac546846fe06bbcff749a0de63cf66d25f6fe Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 19 Nov 2025 08:07:58 +0000 Subject: [PATCH 1/4] Remove AsyncEnumerable from System.Linq.Async public API --- .../adr/0002-System-Linq-Async-In-Net10.md | 23 +++++----- .../System/Linq/AsyncEnumerableEx.cs | 42 +++++++++++++++++++ .../System/Linq/AsyncEnumerable.cs | 10 ++++- .../System/Linq/Operators/Aggregate.cs | 4 ++ .../System/Linq/Operators/All.cs | 4 ++ .../System/Linq/Operators/Any.cs | 4 ++ .../System/Linq/Operators/AppendPrepend.cs | 4 ++ .../Linq/Operators/AsAsyncEnumerable.cs | 6 ++- .../Linq/Operators/Average.Generated.cs | 4 ++ .../Linq/Operators/Average.Generated.tt | 4 ++ .../System/Linq/Operators/Cast.cs | 4 ++ .../System/Linq/Operators/Concat.cs | 4 ++ .../System/Linq/Operators/Contains.cs | 4 ++ .../System/Linq/Operators/Count.cs | 4 ++ .../System/Linq/Operators/DefaultIfEmpty.cs | 4 ++ .../System/Linq/Operators/Distinct.cs | 4 ++ .../System/Linq/Operators/ElementAt.cs | 4 ++ .../Linq/Operators/ElementAtOrDefault.cs | 4 ++ .../System/Linq/Operators/Empty.cs | 4 ++ .../System/Linq/Operators/Except.cs | 4 ++ .../System/Linq/Operators/First.cs | 4 ++ .../System/Linq/Operators/FirstOrDefault.cs | 4 ++ .../System/Linq/Operators/ForEach.cs | 4 ++ .../System/Linq/Operators/GroupBy.cs | 4 ++ .../System/Linq/Operators/GroupJoin.cs | 4 ++ .../System/Linq/Operators/Intersect.cs | 4 ++ .../System/Linq/Operators/Join.cs | 4 ++ .../System/Linq/Operators/Last.cs | 4 ++ .../System/Linq/Operators/LastOrDefault.cs | 4 ++ .../System/Linq/Operators/LongCount.cs | 4 ++ .../System/Linq/Operators/Max.cs | 4 ++ .../System/Linq/Operators/Min.cs | 4 ++ .../System/Linq/Operators/MinMax.Generated.cs | 4 ++ .../System/Linq/Operators/MinMax.Generated.tt | 4 ++ .../System/Linq/Operators/OfType.cs | 4 ++ .../System/Linq/Operators/OrderBy.cs | 4 ++ .../System/Linq/Operators/Range.cs | 4 +- .../System/Linq/Operators/Repeat.cs | 4 +- .../System/Linq/Operators/Reverse.cs | 4 +- .../Linq/Operators/Select.Opt.Generated.cs | 4 ++ .../Linq/Operators/Select.Opt.Generated.tt | 4 ++ .../System/Linq/Operators/Select.Opt.cs | 4 ++ .../System/Linq/Operators/Select.cs | 4 ++ .../System/Linq/Operators/SelectMany.cs | 4 ++ .../System/Linq/Operators/SequenceEqual.cs | 4 +- .../System/Linq/Operators/Single.cs | 4 ++ .../System/Linq/Operators/SingleOrDefault.cs | 4 ++ .../System/Linq/Operators/Skip.cs | 4 +- .../System/Linq/Operators/SkipLast.cs | 4 +- .../System/Linq/Operators/SkipWhile.cs | 4 ++ .../System/Linq/Operators/Sum.Generated.cs | 4 ++ .../System/Linq/Operators/Sum.Generated.tt | 4 ++ .../System/Linq/Operators/Take.cs | 4 +- .../System/Linq/Operators/TakeLast.cs | 4 +- .../System/Linq/Operators/TakeWhile.cs | 4 ++ .../System/Linq/Operators/ToArray.cs | 4 +- .../Operators/ToAsyncEnumerable.Observable.cs | 4 +- .../Linq/Operators/ToAsyncEnumerable.Task.cs | 4 +- .../System/Linq/Operators/ToDictionary.cs | 4 ++ .../System/Linq/Operators/ToEnumerable.cs | 10 ++++- .../System/Linq/Operators/ToHashSet.cs | 4 +- .../System/Linq/Operators/ToList.cs | 4 +- .../System/Linq/Operators/ToLookup.cs | 4 ++ .../System/Linq/Operators/ToObservable.cs | 5 +-- .../System/Linq/Operators/Union.cs | 4 +- .../Linq/Operators/Where.Opt.Generated.cs | 4 ++ .../Linq/Operators/Where.Opt.Generated.tt | 4 ++ .../System/Linq/Operators/Where.Opt.cs | 4 ++ .../System/Linq/Operators/Where.cs | 4 ++ .../System/Linq/Operators/Zip.cs | 4 ++ ...alTests.SystemInteractiveAsync.verified.cs | 1 + 71 files changed, 307 insertions(+), 46 deletions(-) diff --git a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md index 9c1c06a137..4a06ca9852 100644 --- a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md +++ b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md @@ -4,7 +4,7 @@ ## Status -Proposed. +Accepted. ## Authors @@ -15,7 +15,7 @@ Proposed. As an accident of history, the Rx.NET repository ended up being the de facto implementation of LINQ for `IAsyncEnumerable` from 2019 when .NET Core 3 shipped up until late 2025 when .NET 10 shipped. -This happened because Rx.NET had effectively been the incubator in which `IAsyncEnumerable` was originally developed. Back before .NET Core 3.0, there was no such interface built into .NET, but Rx _did_ define this interface as part of its 'interactive extensions for .NET' feature. It also implemented common LINQ operators for that interface. +This happened because Rx.NET had effectively been the incubator in which `IAsyncEnumerable` was originally developed. Back before .NET Core 3.0, there was no such interface built into .NET, but Rx _did_ define this interface as part of its 'interactive extensions for .NET' feature. (It did this as early as 2010.) It also implemented common LINQ operators for that interface. .NET Core 3.0 defined its own version of this `IAsyncEnumerable`, but the .NET team did not implement LINQ for it at that time. Since the Rx.NET repository already had a fairly complete implementation of LINQ for its original version of `IAsyncEnumerable`, it was fairly easy to adapt this to the new version of `IAsyncEnumerable` built into .NET. Thus `System.Linq.Async` was born. @@ -34,6 +34,8 @@ There are also a couple of cases where functionality simply has not been reprodu A further complication is that some methods in `System.Interactive.Async` clash with methods in `System.Linq.AsyncEnumerable`. For example, `MaxByAsync` and `MinByAsync`. Originally `MinBy` and `MaxBy` were unique to Rx.NET and Ix.NET. But .NET 6.0 added operators with these names to LINQ to Objects. Confusingly, they were slightly different: the Rx.NET and Ix.NET versions recognize that there might not be a single minimum or maximum value, and thus provide a collection of all the entries that are at the maximum value, but the .NET runtime class library versions just pick one arbitrary winner. So at this point, `System.Interactive` renamed its versions to `MinByWithTies` and `MaxByWithTies`. Unfortunately that same change wasn't made in `System.Interactive.Async`, so we now have the same situation with `System.Linq.AsyncEnumerable`: the .NET runtime class libraries now define `MinByAsync` and `MaxByAsync` extension methods for `IAsyncEnumerable`, and these take the same arguments as the ones in `System.Interactive.Async`, but have a different return type, and have different behaviour! +One more important point to consider is that although LINQ to `IAsyncEnumerable` _mostly_ consists of extension methods, there are a few static methods. (E.g., `AsyncEnumerable.Range`, which the .NET library implements, and `AsyncEnumerable.Create`, which is does not.) With extension methods, the compiler does not have a problem with multiple identically-named types in different assemblies all defining extension methods as long as the individual methods do not conflict. However, non-extension methods are a problem. If `System.Linq.Async` were to continue to define a public `AsyncEnumerable` type, then calls to `AsyncEnumerable.Range` would fail to compile: even though there would only be a single `Range` method (supplied by the new `System.Linq.AsyncEnumerable`) this would fail to compile because `AsyncEnumerable` itself is an ambiguous class name. So it will be necessary for the public API of `System.Linq.Async` v7 not to define an `AsyncEnumerable` type. This places some limits on how far we can go with source-level compatibility. (Binary compatibility is not a problem because the runtime assemblies can continue to define this type.) + ## Decision @@ -41,13 +43,14 @@ The next Ix.NET release will: 1. add a reference to `System.Linq.AsyncEnumerable` and `System.Interactive.Async` in `System.Linq.Async` 2. remove from `System.Linq.Async`'s and `System.Interactive.Async`'s publicly visible API (ref assemblies) all `IAsyncEnumerable` extension methods for which direct replacements exist (adding `MinByWithTiesAsync` and `MaxByWithTiesAsync` for the case where the new .NET runtime library methods actually have slightly different functionality) -3. add [Obsolete] attribute for members of `AsyncEnumerable` for which `System.Linq.AsyncEnumerable` offers replacements that require code changes to use (e.g., `WhereAwait`, which is replaced by an overload of `Where`) -4. `AsyncEnumerable` methods that are a bad idea and that should probably have never existing (the ones that do sync over async, e.g. `ToEnumerable`) are marked as `Obsolete` and will not be replaced; note that although `ToObservable` has issues that meant the .NET team decided not to replicate it, the main issue is that it embeds opinions, and not that there's anything fundamentally broken about it, so we do not include `ToObservable` in this category -5. remaining methods of `AsyncEnumerable` (where `System.Linq.AsyncEnumerable` offers no equivalent) are removed from the publicly visible API of `System.Linq.Async`, with identical replacements being defined by `AsyncEnumerableEx` in `System.Interactive -6. mark `IAsyncGrouping` as obsolete -7. mark the public `IAsyncIListProvider` as obsolete, and define a non-public version for continued internal use in `System.Interactive.Linq` -8. continue to provide the full `System.Linq.Async` API in the `lib` assemblies to provide binary compatibility -9. mark the `System.Linq.Async` NuGet package as obsolete, and recommend the use of `System.Linq.AsyncEnumerable` and/or `System.Interactive.Async` instead +4. Rename `AsyncEnumerable` to `AsyncEnumerableDeprecated` in the public API (reference assemblies; the old name will be retained in runtime assemblies for binary compatibility) to avoid errors arising from there being two definitions of `AsyncEnumerable` in the same namespace +5. add [Obsolete] attribute for members of `AsyncEnumerableDeprecated` for which `System.Linq.AsyncEnumerable` offers replacements that require code changes to use (e.g., `WhereAwait`, which is replaced by an overload of `Where`) +6. the `AsyncEnumerable.ToEnumerable` method that was a bad idea and that should probably have never existing has been marked as `Obsolete` and will not be replaced; note that although `ToObservable` has issues that meant the .NET team decided not to replicate it, the main issue is that it embeds opinions, and not that there's anything fundamentally broken about it, so we do not include `ToObservable` in this category +7. remaining methods of `AsyncEnumerable` (where `System.Linq.AsyncEnumerable` offers no equivalent) are removed from the publicly visible API of `System.Linq.Async`, with identical replacements being defined by `AsyncEnumerableEx` in `System.Interactive +8. mark `IAsyncGrouping` as obsolete +9. mark the public `IAsyncIListProvider` as obsolete, and define a non-public version for continued internal use in `System.Interactive.Linq` +10. continue to provide the full `System.Linq.Async` API in the `lib` assemblies to provide binary compatibility +11. mark the `System.Linq.Async` NuGet package as obsolete, and recommend the use of `System.Linq.AsyncEnumerable` and/or `System.Interactive.Async` instead The main effect of this is that code that had been using the `System.Linq.Async` implementation of LINQ for `IAsyncEnumerable` will, in most cases, now be using the .NET runtime library implementation if it is rebuilt against this new version of `System.Linq.Async`. @@ -79,4 +82,4 @@ Code that had been written to use `System.Linq.Async` v6 that upgrades to .NET 1 The situation is very similar for code written to use `System.Linq.Async` v6 that does _not_ upgrade to .NET 10 (e.g. either it stays on .NET 8 or 9, or it targets .NET Framework or .NET Standard) but which newly acquires a dependency on `System.Linq.AsyncEnumerable` either because the developer adds it, or because they update to a new version of some component which adds it as a new transitive dependency. -Code written to use `System.Linq.Async` v6 that changes nothing at all but, which is rebuilt after `System.Linq.Async` v7 is released, will see a warning that the package is now deprecated. They can fix this warning by removing the package and adding a reference to `System.Linq.AsyncEnumerable` or `System.Interactive.Async` or both as required. \ No newline at end of file +Code written to use `System.Linq.Async` v6 that changes nothing at all but, which is rebuilt after `System.Linq.Async` v7 is released, will see a warning that the package is now deprecated. Developers can fix this warning by removing the package and adding a reference to `System.Linq.AsyncEnumerable` or `System.Interactive.Async` or both as required. \ No newline at end of file diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs index 803e2d32dd..3aa992e73d 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Threading; + namespace System.Linq { /// @@ -10,5 +13,44 @@ namespace System.Linq /// public static partial class AsyncEnumerableEx { + // NOTE: This was originally in System.Linq.Async, but was moved here because we are + // deprecating that package. It's not clear if this is still useful: there was + // a REVIEW comment against this code saying "Async iterators can be + // used to implement these interfaces." We retain this mainly so that anyone + // who was using it can still have it. Unfortunately there's no way to do that + // without introducing a source-level breaking change: we've had to move it out + // of AsyncEnumerable because we can't have System.Linq.Async's public API defining + // a class of that name. (It causes amibuigous type errors if you try to invoke + // a static method such as AsyncEnumerable.Range: even if System.Linq.Async doesn't + // define Range on its AsyncEnumerable, the compiler chokes on the fact that there + // are two AsyncEnumerable types.) + + /// + /// Creates a new enumerable using the specified delegates implementing the members of . + /// + /// The type of the elements returned by the enumerable sequence. + /// The delegate implementing the method. + /// A new enumerable instance. + public static IAsyncEnumerable Create(Func> getAsyncEnumerator) + { + if (getAsyncEnumerator == null) + throw Error.ArgumentNull(nameof(getAsyncEnumerator)); + + return new AnonymousAsyncEnumerable(getAsyncEnumerator); + } + + private sealed class AnonymousAsyncEnumerable : IAsyncEnumerable + { + private readonly Func> _getEnumerator; + + public AnonymousAsyncEnumerable(Func> getEnumerator) => _getEnumerator = getEnumerator; + + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); // NB: [LDM-2018-11-28] Equivalent to async iterator behavior. + + return _getEnumerator(cancellationToken); + } + } } } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/AsyncEnumerable.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/AsyncEnumerable.cs index 4c8c9c9b1e..8855bf8818 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/AsyncEnumerable.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/AsyncEnumerable.cs @@ -7,14 +7,19 @@ namespace System.Linq { +#if INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC /// /// Provides a set of extension methods for . /// public static partial class AsyncEnumerable { // - // REVIEW: Create methods may not belong in System.Linq.Async. Async iterators can be - // used to implement these interfaces. Move to System.Interactive.Async? + // NOTE: This has been replaced in v7 by a method of the same name on + // System.Interactive.Async's AsyncEnumerableEx class. This is a breaking + // change but it's necessary because we can't allow System.Linq.Async's + // ref assembly to define a public AsyncEnumerable type. If we do that, + // it will conflict with System.Linq.AsyncEnumerable, preventing direct + // invocation of static methods. (E.g., AsyncEnumerable.Range.) // /// @@ -45,4 +50,5 @@ public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToke } } } +#endif // INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Aggregate.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Aggregate.cs index a6c3c11f89..43cd5179db 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Aggregate.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Aggregate.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.aggregateasync?view=net-9.0-pp#system-linq-asyncenumerable-aggregateasync-1(system-collections-generic-iasyncenumerable((-0))-system-func((-0-0-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/All.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/All.cs index 9aff8ab3d7..0ff8ba293a 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/All.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/All.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.allasync?view=net-9.0-pp#system-linq-asyncenumerable-allasync-1(system-collections-generic-iasyncenumerable((-0))-system-func((-0-system-boolean))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Any.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Any.cs index 8b809fa973..f6f4208c14 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Any.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Any.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.anyasync?view=net-9.0-pp#system-linq-asyncenumerable-anyasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AppendPrepend.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AppendPrepend.cs index d533b595d0..c912f5ef80 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AppendPrepend.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AppendPrepend.cs @@ -10,7 +10,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.append?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AsAsyncEnumerable.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AsAsyncEnumerable.cs index 166f741387..97858c8a17 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AsAsyncEnumerable.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/AsAsyncEnumerable.cs @@ -6,8 +6,12 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable - // NB: Synchronous LINQ to Objects doesn't hide the implementation of the source either. +#endif + // NB: Synchronous LINQ to Objects doesn't hide the implementation of the source either. { #if INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC // Note: this one isn't actually in the System.Linq.AsyncEnumerable package, so we've moved it diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.cs index 9de2ca467b..6d58abf39b 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES /// diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.tt b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.tt index 25292101bd..73e6aacf07 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.tt +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Average.Generated.tt @@ -14,7 +14,11 @@ using System.Threading.Tasks; namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { <# var os = new[] diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Cast.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Cast.cs index 3d54b9543c..ee08bc6dfb 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Cast.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Cast.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { // NB: This is a non-standard LINQ operator, because we don't have a non-generic IAsyncEnumerable. // We're keeping it to enable `from T x in xs` binding in C#. diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Concat.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Concat.cs index 3733b3248a..67ff2a58ea 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Concat.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Concat.cs @@ -9,7 +9,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.concat?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Contains.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Contains.cs index 1efc873042..6a509b07f4 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Contains.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Contains.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.containsasync?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Count.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Count.cs index 43b43e913d..32673a29fc 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Count.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Count.cs @@ -9,7 +9,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.countasync?view=net-9.0-pp#system-linq-asyncenumerable-countasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/DefaultIfEmpty.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/DefaultIfEmpty.cs index a3aabbd51d..db256721a9 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/DefaultIfEmpty.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/DefaultIfEmpty.cs @@ -9,7 +9,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES /// diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Distinct.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Distinct.cs index fda821da3b..c61681ac99 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Distinct.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Distinct.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.distinct?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAt.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAt.cs index 9ccf328665..6bb8d0ec97 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAt.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAt.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.elementatasync?view=net-9.0-pp#system-linq-asyncenumerable-elementatasync-1(system-collections-generic-iasyncenumerable((-0))-system-int32-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAtOrDefault.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAtOrDefault.cs index a22dd503fd..06bc44eca8 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAtOrDefault.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAtOrDefault.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.elementatordefaultasync?view=net-9.0-pp#system-linq-asyncenumerable-elementatordefaultasync-1(system-collections-generic-iasyncenumerable((-0))-system-int32-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Empty.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Empty.cs index a6d975a4df..8915ee1072 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Empty.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Empty.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.empty?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Except.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Except.cs index 1bdfa72977..75a105c775 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Except.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Except.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.except?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/First.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/First.cs index 55df31271c..0d9e4cb29f 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/First.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/First.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.firstasync?view=net-9.0-pp#system-linq-asyncenumerable-firstasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/FirstOrDefault.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/FirstOrDefault.cs index ea1a5345b1..2922b4a44a 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/FirstOrDefault.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/FirstOrDefault.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.firstordefaultasync?view=net-9.0-pp#system-linq-asyncenumerable-firstordefaultasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ForEach.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ForEach.cs index 6648c0f118..ef3c74b341 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ForEach.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ForEach.cs @@ -10,7 +10,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { // REVIEW: Once we have C# 8.0 language support, we may want to do away with these methods. An open question is how to // provide support for cancellation, which could be offered through WithCancellation on the source. If we still diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupBy.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupBy.cs index 9f22100ac8..dec0a06dd5 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupBy.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupBy.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // The next two methods are replaced by a single method in System.Linq.AsyncEnumerable: diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupJoin.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupJoin.cs index 397c62d060..c08646d472 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupJoin.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/GroupJoin.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.groupjoin?view=net-9.0-pp#system-linq-asyncenumerable-groupjoin-4(system-collections-generic-iasyncenumerable((-0))-system-collections-generic-iasyncenumerable((-1))-system-func((-0-2))-system-func((-1-2))-system-func((-0-system-collections-generic-ienumerable((-1))-3))-system-collections-generic-iequalitycomparer((-2))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Intersect.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Intersect.cs index 1e5639e6ce..f5ca350171 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Intersect.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Intersect.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.intersect?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Join.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Join.cs index e55ac787ea..cb123a328d 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Join.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Join.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.join?view=net-9.0-pp#system-linq-asyncenumerable-join-4(system-collections-generic-iasyncenumerable((-0))-system-collections-generic-iasyncenumerable((-1))-system-func((-0-2))-system-func((-1-2))-system-func((-0-1-3))-system-collections-generic-iequalitycomparer((-2))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Last.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Last.cs index b4087d545b..9871a55412 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Last.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Last.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.lastasync?view=net-9.0-pp#system-linq-asyncenumerable-lastasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LastOrDefault.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LastOrDefault.cs index 1a1c2fe537..279cd6a0bf 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LastOrDefault.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LastOrDefault.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.lastordefaultasync?view=net-9.0-pp#system-linq-asyncenumerable-lastordefaultasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LongCount.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LongCount.cs index e62e94e7fd..3485bb8ecc 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LongCount.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/LongCount.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.longcountasync?view=net-9.0-pp#system-linq-asyncenumerable-longcountasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs index a15dbd3937..e45233a43c 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.maxasync?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs index 617d5070b2..0d90073e10 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.minasync?view=net-9.0-pp diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.cs index d5c397f036..cfca489740 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES /// diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.tt b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.tt index 2f13666bf0..20b4695cbd 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.tt +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinMax.Generated.tt @@ -14,7 +14,11 @@ using System.Threading.Tasks; namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { <# foreach (var m in new[] { "Max", "Min" }) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OfType.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OfType.cs index bbd94d9392..64ab8c5d77 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OfType.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OfType.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { // REVIEW: This is a non-standard LINQ operator, because we don't have a non-generic IAsyncEnumerable. // diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OrderBy.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OrderBy.cs index 3b3b60d572..1f21154cde 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OrderBy.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/OrderBy.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.orderby?view=net-9.0-pp#system-linq-asyncenumerable-orderby-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Range.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Range.cs index 77bf5a21ba..35b55a24d9 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Range.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Range.cs @@ -9,9 +9,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.range?view=net-9.0-pp /// @@ -147,6 +147,6 @@ async ValueTask Core() } } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Repeat.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Repeat.cs index 45f12bace6..1fc41ebdc6 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Repeat.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Repeat.cs @@ -8,9 +8,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.repeat?view=net-9.0-pp /// @@ -102,6 +102,6 @@ protected override async ValueTask MoveNextCore() return false; } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Reverse.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Reverse.cs index 54732b0d1e..07e5b3dbf1 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Reverse.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Reverse.cs @@ -9,9 +9,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.reverse?view=net-9.0-pp /// @@ -118,6 +118,6 @@ protected override async ValueTask MoveNextCore() return false; } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.cs index 82c34b237d..5fa8b77e68 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.cs @@ -7,7 +7,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { private sealed class CombinedSelectors2 : ICombinedSelectors { diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.tt b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.tt index 2e0ddda692..1988bda6a7 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.tt +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.Generated.tt @@ -16,7 +16,11 @@ using System.Threading.Tasks; namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { <# for (var i = 2; i <= maxCombine; i++) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.cs index 50bedce25d..b188e2ea60 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.Opt.cs @@ -7,7 +7,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { private static Func CombineSelectors(Func selector1, Func selector2) { diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.cs index 491b89ca8c..55d47ec951 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Select.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.select?view=net-9.0-pp#system-linq-asyncenumerable-select-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SelectMany.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SelectMany.cs index 878e42e6bb..88ef986574 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SelectMany.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SelectMany.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.selectmany?view=net-9.0-pp#system-linq-asyncenumerable-selectmany-3(system-collections-generic-iasyncenumerable((-0))-system-func((-0-system-collections-generic-iasyncenumerable((-1))))-system-func((-0-1-2))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SequenceEqual.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SequenceEqual.cs index df2fb804b3..912ee83e51 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SequenceEqual.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SequenceEqual.cs @@ -8,9 +8,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.sequenceequalasync?view=net-9.0-pp // The method above covers the next two overloads because it supplies a default null value for comparer. @@ -88,6 +88,6 @@ static async ValueTask Core(IAsyncEnumerable first, IAsyncEnumera return !await e2.MoveNextAsync(); } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Single.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Single.cs index aa0ae170e1..62adefcf70 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Single.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Single.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.singleasync?view=net-9.0-pp#system-linq-asyncenumerable-singleasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SingleOrDefault.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SingleOrDefault.cs index c7aa9edcdc..df96d6a970 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SingleOrDefault.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SingleOrDefault.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.singleordefaultasync?view=net-9.0-pp#system-linq-asyncenumerable-singleordefaultasync-1(system-collections-generic-iasyncenumerable((-0))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Skip.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Skip.cs index fb463e4149..57ab294571 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Skip.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Skip.cs @@ -6,9 +6,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.skip?view=net-9.0-pp /// @@ -47,6 +47,6 @@ public static IAsyncEnumerable Skip(this IAsyncEnumerable(source, count, -1); } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipLast.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipLast.cs index b47f97ccde..8066d47800 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipLast.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipLast.cs @@ -9,9 +9,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.skiplast?view=net-9.0-pp /// @@ -71,6 +71,6 @@ static async IAsyncEnumerable Core(IAsyncEnumerable source, in } } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipWhile.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipWhile.cs index 7695e1188a..1de6f599e9 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipWhile.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/SkipWhile.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.skipwhile?view=net-9.0-pp#system-linq-asyncenumerable-skipwhile-1(system-collections-generic-iasyncenumerable((-0))-system-func((-0-system-boolean))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.cs index f234bcd15d..e02cab3898 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES /// diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.tt b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.tt index a348445cfd..1096f3b897 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.tt +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Sum.Generated.tt @@ -14,7 +14,11 @@ using System.Threading.Tasks; namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { <# var os = new[] diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Take.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Take.cs index b7d9b547f3..b68989d83d 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Take.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Take.cs @@ -6,9 +6,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.take?view=net-9.0-pp#system-linq-asyncenumerable-take-1(system-collections-generic-iasyncenumerable((-0))-system-int32) @@ -41,6 +41,6 @@ public static IAsyncEnumerable Take(this IAsyncEnumerable(source, 0, count - 1); } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeLast.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeLast.cs index 76c1a641ec..1ef75433fb 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeLast.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeLast.cs @@ -9,9 +9,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.takelast?view=net-9.0-pp @@ -81,6 +81,6 @@ static async IAsyncEnumerable Core(IAsyncEnumerable source, in while (queue.Count > 0); } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeWhile.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeWhile.cs index 1fc82ef62f..26b13f453e 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeWhile.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/TakeWhile.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.takewhile?view=net-9.0-pp#system-linq-asyncenumerable-takewhile-1(system-collections-generic-iasyncenumerable((-0))-system-func((-0-system-boolean))) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToArray.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToArray.cs index 34009ae906..812ea300d9 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToArray.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToArray.cs @@ -8,9 +8,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.toarrayasync?view=net-9.0-pp /// @@ -32,6 +32,6 @@ public static ValueTask ToArrayAsync(this IAsyncEnumerable MoveNextCore() return false; } } -#endif // INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC } +#endif // INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs index 0fa9fcb3eb..9af5ea05fe 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.todictionaryasync?view=net-9.0-pp#system-linq-asyncenumerable-todictionaryasync-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-collections-generic-iequalitycomparer((-1))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToEnumerable.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToEnumerable.cs index bddecb8a78..2c4d01c83b 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToEnumerable.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToEnumerable.cs @@ -7,10 +7,16 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { - // REVIEW: This type of blocking is an anti-pattern. We may want to move it to System.Interactive.Async - // and remove it from System.Linq.Async API surface. + // NOTE: This type of blocking is an anti-pattern. We should never have offered it. + // It is being left here for binary compatibility for those who were using it, + // and the publicly visible version is marked as Obsolete so we can explain + // why it should not be used. /// /// Converts an async-enumerable sequence to an enumerable sequence. diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs index a2cb32a046..8dda7ca248 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs @@ -8,9 +8,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tohashsetasync?view=net-9.0-pp // That one overload covers the next two methods, because it supplieds a default comparer. @@ -55,6 +55,6 @@ static async ValueTask> Core(IAsyncEnumerable source, return set; } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs index d5ed2294ad..d996f0d139 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs @@ -8,9 +8,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tolistasync?view=net-9.0-pp /// @@ -44,6 +44,6 @@ static async ValueTask> Core(IAsyncEnumerable source, Can return list; } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs index a57f98deae..48495b32eb 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tolookupasync?view=net-9.0-pp#system-linq-asyncenumerable-tolookupasync-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-collections-generic-iequalitycomparer((-1))-system-threading-cancellationtoken) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToObservable.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToObservable.cs index 0a6ea1a3d6..db37a7e021 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToObservable.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToObservable.cs @@ -6,10 +6,9 @@ namespace System.Linq { +#if INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC public static partial class AsyncEnumerable { -#if INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC - // Moved to AsyncEnumerableEx in System.Interactive.Async. // System.Linq.AsyncEnumerable has chosen not to implement this. We continue to implement this because // we believe it is a useful feature, but since it's now in the category of LINQ-adjacent functionality @@ -86,6 +85,6 @@ async void Core() return ctd; } } -#endif // INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC } +#endif // INCLUDE_RELOCATED_TO_INTERACTIVE_ASYNC } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs index 7ac699ecbc..57ed1531dc 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs @@ -9,9 +9,9 @@ namespace System.Linq { +#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES public static partial class AsyncEnumerable { -#if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.union?view=net-9.0-pp // That one overload covers the next two methods, because it supplieds a default comparer. @@ -294,6 +294,6 @@ internal override UnionAsyncIterator Union(IAsyncEnumerable ne return new UnionAsyncIteratorN(_sources.Add(next), _headIndex + 1, _comparer); } } -#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } +#endif // INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES } diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.cs index 9afdc0cb26..db35a2b27c 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.cs @@ -7,7 +7,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { private sealed class CombinedPredicates2 : ICombinedPredicates { diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.tt b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.tt index 0a66a89fae..523148ef0a 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.tt +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.Generated.tt @@ -16,7 +16,11 @@ using System.Threading.Tasks; namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { <# for (var i = 2; i <= maxCombine; i++) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.cs index 2d72df0f85..dc189ae53c 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.Opt.cs @@ -7,7 +7,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { private static Func CombinePredicates(Func predicate1, Func predicate2) { diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.cs index db7815717f..2a0c414e33 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Where.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Zip.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Zip.cs index a13919516c..e166b52e94 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Zip.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Zip.cs @@ -8,7 +8,11 @@ namespace System.Linq { +#if REFERENCE_ASSEMBLY + public static partial class AsyncEnumerableDeprecated +#else public static partial class AsyncEnumerable +#endif { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.zip?view=net-9.0-pp#system-linq-asyncenumerable-zip-2(system-collections-generic-iasyncenumerable((-0))-system-collections-generic-iasyncenumerable((-1))) diff --git a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs index 50fe605b3b..266c344416 100644 --- a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs +++ b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs @@ -54,6 +54,7 @@ public static System.Collections.Generic.IAsyncEnumerable Catch Concat(this System.Collections.Generic.IAsyncEnumerable> sources) { } public static System.Collections.Generic.IAsyncEnumerable Concat(params System.Collections.Generic.IAsyncEnumerable[] sources) { } public static System.Collections.Generic.IAsyncEnumerable Concat(this System.Collections.Generic.IEnumerable> sources) { } + public static System.Collections.Generic.IAsyncEnumerable Create(System.Func> getAsyncEnumerator) { } public static System.Collections.Generic.IAsyncEnumerable Defer(System.Func> factory) { } public static System.Collections.Generic.IAsyncEnumerable Defer(System.Func>> factory) { } public static System.Collections.Generic.IAsyncEnumerable Defer(System.Func>> factory) { } From ff3e3e398124fcfce5e999388fa0caf111d6d318 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 19 Nov 2025 15:16:39 +0000 Subject: [PATCH 2/4] Fix typos in ADR --- Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md index 4a06ca9852..33034fd141 100644 --- a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md +++ b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md @@ -45,8 +45,8 @@ The next Ix.NET release will: 2. remove from `System.Linq.Async`'s and `System.Interactive.Async`'s publicly visible API (ref assemblies) all `IAsyncEnumerable` extension methods for which direct replacements exist (adding `MinByWithTiesAsync` and `MaxByWithTiesAsync` for the case where the new .NET runtime library methods actually have slightly different functionality) 4. Rename `AsyncEnumerable` to `AsyncEnumerableDeprecated` in the public API (reference assemblies; the old name will be retained in runtime assemblies for binary compatibility) to avoid errors arising from there being two definitions of `AsyncEnumerable` in the same namespace 5. add [Obsolete] attribute for members of `AsyncEnumerableDeprecated` for which `System.Linq.AsyncEnumerable` offers replacements that require code changes to use (e.g., `WhereAwait`, which is replaced by an overload of `Where`) -6. the `AsyncEnumerable.ToEnumerable` method that was a bad idea and that should probably have never existing has been marked as `Obsolete` and will not be replaced; note that although `ToObservable` has issues that meant the .NET team decided not to replicate it, the main issue is that it embeds opinions, and not that there's anything fundamentally broken about it, so we do not include `ToObservable` in this category -7. remaining methods of `AsyncEnumerable` (where `System.Linq.AsyncEnumerable` offers no equivalent) are removed from the publicly visible API of `System.Linq.Async`, with identical replacements being defined by `AsyncEnumerableEx` in `System.Interactive +6. the `AsyncEnumerable.ToEnumerable` method that was a bad idea and that should probably have never existed has been marked as `Obsolete` and will not be replaced; note that although `ToObservable` has issues that meant the .NET team decided not to replicate it, the main issue is that it embeds opinions, and not that there's anything fundamentally broken about it, so we do not include `ToObservable` in this category +7. remaining methods of `AsyncEnumerable` (where `System.Linq.AsyncEnumerable` offers no equivalent) are removed from the publicly visible API of `System.Linq.Async`, with identical replacements being defined by `AsyncEnumerableEx` in `System.Interactive.Async` 8. mark `IAsyncGrouping` as obsolete 9. mark the public `IAsyncIListProvider` as obsolete, and define a non-public version for continued internal use in `System.Interactive.Linq` 10. continue to provide the full `System.Linq.Async` API in the `lib` assemblies to provide binary compatibility From b4791c49260210647c87099cc9fe59331359d6fd Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 19 Nov 2025 15:18:02 +0000 Subject: [PATCH 3/4] Fix typos in comments --- .../System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs | 2 +- .../System.Linq.Async/System/Linq/Operators/ToDictionary.cs | 2 +- .../System.Linq.Async/System/Linq/Operators/ToHashSet.cs | 2 +- .../System.Linq.Async/System/Linq/Operators/ToLookup.cs | 4 ++-- .../Source/System.Linq.Async/System/Linq/Operators/Union.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs index 3aa992e73d..073ef55db1 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/AsyncEnumerableEx.cs @@ -20,7 +20,7 @@ public static partial class AsyncEnumerableEx // who was using it can still have it. Unfortunately there's no way to do that // without introducing a source-level breaking change: we've had to move it out // of AsyncEnumerable because we can't have System.Linq.Async's public API defining - // a class of that name. (It causes amibuigous type errors if you try to invoke + // a class of that name. (It causes ambiguous type errors if you try to invoke // a static method such as AsyncEnumerable.Range: even if System.Linq.Async doesn't // define Range on its AsyncEnumerable, the compiler chokes on the fact that there // are two AsyncEnumerable types.) diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs index 9af5ea05fe..0bec1eea3d 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToDictionary.cs @@ -16,7 +16,7 @@ public static partial class AsyncEnumerable { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.todictionaryasync?view=net-9.0-pp#system-linq-asyncenumerable-todictionaryasync-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-collections-generic-iequalitycomparer((-1))-system-threading-cancellationtoken) - // That one overload covers the next two methods, because it supplieds a default comparer. + // That one overload covers the next two methods, because it supplies a default comparer. /// /// Creates a dictionary from an async-enumerable sequence according to a specified key selector function. diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs index 8dda7ca248..6e69fb59b8 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToHashSet.cs @@ -12,7 +12,7 @@ namespace System.Linq public static partial class AsyncEnumerable { // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tohashsetasync?view=net-9.0-pp - // That one overload covers the next two methods, because it supplieds a default comparer. + // That one overload covers the next two methods, because it supplies a default comparer. /// /// Creates a hash set from an async-enumerable sequence. diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs index 48495b32eb..7ff061137d 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToLookup.cs @@ -16,7 +16,7 @@ public static partial class AsyncEnumerable { #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tolookupasync?view=net-9.0-pp#system-linq-asyncenumerable-tolookupasync-2(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-collections-generic-iequalitycomparer((-1))-system-threading-cancellationtoken) - // That one overload covers the next two methods, because it supplieds a default comparer. + // That one overload covers the next two methods, because it supplies a default comparer. /// /// Creates a lookup from an async-enumerable sequence according to a specified key selector function. @@ -131,7 +131,7 @@ static async ValueTask> Core(IAsyncEnumerable so #if INCLUDE_SYSTEM_LINQ_ASYNCENUMERABLE_DUPLICATES // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.tolookupasync?view=net-9.0-pp#system-linq-asyncenumerable-tolookupasync-3(system-collections-generic-iasyncenumerable((-0))-system-func((-0-1))-system-func((-0-2))-system-collections-generic-iequalitycomparer((-1))-system-threading-cancellationtoken) - // That one overload covers the next two methods, because it supplieds a default comparer. + // That one overload covers the next two methods, because it supplies a default comparer. /// /// Creates a lookup from an async-enumerable sequence according to a specified key selector function, and an element selector function. diff --git a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs index 57ed1531dc..1b6407ded9 100644 --- a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs +++ b/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Union.cs @@ -13,7 +13,7 @@ namespace System.Linq public static partial class AsyncEnumerable { // https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable.union?view=net-9.0-pp - // That one overload covers the next two methods, because it supplieds a default comparer. + // That one overload covers the next two methods, because it supplies a default comparer. /// /// Produces the set union of two sequences by using the default equality comparer. From cb2ac446c04e75e0805d6f4132473086c4d977ff Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Wed, 19 Nov 2025 19:09:47 +0000 Subject: [PATCH 4/4] Fix typo in ADR --- Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md index 33034fd141..4c3c78991b 100644 --- a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md +++ b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md @@ -34,7 +34,7 @@ There are also a couple of cases where functionality simply has not been reprodu A further complication is that some methods in `System.Interactive.Async` clash with methods in `System.Linq.AsyncEnumerable`. For example, `MaxByAsync` and `MinByAsync`. Originally `MinBy` and `MaxBy` were unique to Rx.NET and Ix.NET. But .NET 6.0 added operators with these names to LINQ to Objects. Confusingly, they were slightly different: the Rx.NET and Ix.NET versions recognize that there might not be a single minimum or maximum value, and thus provide a collection of all the entries that are at the maximum value, but the .NET runtime class library versions just pick one arbitrary winner. So at this point, `System.Interactive` renamed its versions to `MinByWithTies` and `MaxByWithTies`. Unfortunately that same change wasn't made in `System.Interactive.Async`, so we now have the same situation with `System.Linq.AsyncEnumerable`: the .NET runtime class libraries now define `MinByAsync` and `MaxByAsync` extension methods for `IAsyncEnumerable`, and these take the same arguments as the ones in `System.Interactive.Async`, but have a different return type, and have different behaviour! -One more important point to consider is that although LINQ to `IAsyncEnumerable` _mostly_ consists of extension methods, there are a few static methods. (E.g., `AsyncEnumerable.Range`, which the .NET library implements, and `AsyncEnumerable.Create`, which is does not.) With extension methods, the compiler does not have a problem with multiple identically-named types in different assemblies all defining extension methods as long as the individual methods do not conflict. However, non-extension methods are a problem. If `System.Linq.Async` were to continue to define a public `AsyncEnumerable` type, then calls to `AsyncEnumerable.Range` would fail to compile: even though there would only be a single `Range` method (supplied by the new `System.Linq.AsyncEnumerable`) this would fail to compile because `AsyncEnumerable` itself is an ambiguous class name. So it will be necessary for the public API of `System.Linq.Async` v7 not to define an `AsyncEnumerable` type. This places some limits on how far we can go with source-level compatibility. (Binary compatibility is not a problem because the runtime assemblies can continue to define this type.) +One more important point to consider is that although LINQ to `IAsyncEnumerable` _mostly_ consists of extension methods, there are a few static methods. (E.g., `AsyncEnumerable.Range`, which the .NET library implements, and `AsyncEnumerable.Create`, which it does not.) With extension methods, the compiler does not have a problem with multiple identically-named types in different assemblies all defining extension methods as long as the individual methods do not conflict. However, non-extension methods are a problem. If `System.Linq.Async` were to continue to define a public `AsyncEnumerable` type, then calls to `AsyncEnumerable.Range` would fail to compile: even though there would only be a single `Range` method (supplied by the new `System.Linq.AsyncEnumerable`) this would fail to compile because `AsyncEnumerable` itself is an ambiguous class name. So it will be necessary for the public API of `System.Linq.Async` v7 not to define an `AsyncEnumerable` type. This places some limits on how far we can go with source-level compatibility. (Binary compatibility is not a problem because the runtime assemblies can continue to define this type.) ## Decision