-
Notifications
You must be signed in to change notification settings - Fork 782
Description
Although we have modified System.Linq.Async in preparation for the availability of the .NET runtime libraries' System.Linq.AsyncEnumerable, it turns out we also need to make some tweaks to System.Interactive.Async.
Generally speaking, things go in System.Interactive and System.Interactive.Async if they are LINQ-like features not not core LINQ features. So historically, System.Interactive has offered things like Scan: it certainly feels like LINQ (it's a close relative of Aggregate) but since it's not a standard operator, the .NET runtime library does not provider it, and thus System.Interactive steps in to fill the gap.
(Another way to look at System.Interactive is that it fills out the set of LINQ to Objects operators to match the set of LINQ operators provided by Rx.NET.)
The waters get a little muddied when the .NET Runtime occasionally realises that the Rx.NET team were onto something, and adds an operator that was previously deemed to be a non-standard Rx-ism. Over time, some operators have been removed from System.Interactive because they became part of standard LINQ.
In theory, the System.Linq.Async/System.Interactive.Async split is the same thing, just for IAsyncEnumerable<T>: standard operators go in the former, and non-standard bonus LINQ operators go in the latter. And now that the .NET runtime team are supplying LINQ for IAsyncEnumerable<T> in their System.Linq.AsyncEnumerable package, this split should now be System.Linq.AsyncEnumerable/System.Interactive.Async.
However, it turns out that the division between 'standard LINQ' and 'bonus LINQ' has moved a bit, and although System.Interactive has had no choice but to keep up (to avoid causing conflicts) it seems that the System.Linq.Async/System.Interactive.Async split wasn't kept in sync.
For example, MaxBy was originally a bonus operator. Then in .NET 6.0, the .NET runtime class libraries added an operator with this name. Just to add to the fun, it didn't actually do the same thing as the Ix.NET MaxBy, and so Ix.NET 6.0 deprecated its own MaxBy and replaced it with MaxByWithTies. But for some reason, System.Linq.Async/System.Interactive.Async weren't modified in the same way to match.
That's a problem today because .NET's System.Linq.AsyncEnumerable now supplies a MaxByAsync, considering it to be a 'standard LINQ' operator, but System.Interactive.Async continues to define an operator with the same name and argument types, but different behaviour and a different return type.
We need to hide System.Interactive.Async's MaxByAsync, and replace it with a new MaxByWithTies. Similarly for MinByAsync.