-
Notifications
You must be signed in to change notification settings - Fork 779
Description
The technique we've been using up until now in the Ix.NET v7 previews to enable System.Linq.Async to step out of the way of .NET 10's new System.Linq.AsyncEnumerable package works for extension methods, but I've realised there's a problem for straightforward static method invocation, e.g.:
IAsyncEnumerable<int> xs= AsyncEnumerable.Range(1, 10);This works today on .NET 8.0 and 9.0 with System.Linq.Async. It also works on .NET 10 if you don't have a reference to System.Linq.Async. But if you are on .NET 10 (or you're on 8.0 or 9.0 and have added a reference to the new System.Linq.AsyncEnumerable package) and you also have a reference to System.Linq.Async, that line of code will produce this error:
error CS0121: The call is ambiguous between the following methods or properties: 'AsyncEnumerable.Select<TSource, TResult>(IAsyncEnumerable<TSource>, Func<TSource, int, TResult>)' and 'AsyncEnumerable.Select<TSource, TResult>(IAsyncEnumerable<TSource>, Func<TSource, CancellationToken, ValueTask<TResult>>)'
The problem is that although System.Linq.Async has hidden all the individual methods that clash with System.Linq.AsyncEnumerable, it continues to define a public AsyncEnumerable type. It does that so that it can continue to provide the methods that System.Linq.AsyncEnumerable has not replaced and that need to be annotated with Obsolete.
(Note that not all of the methods that System.Linq.AsyncEnumerable has not replaced are obsolete. Some have moved into System.Interactive.Async. But the ones that use non-standard naming coventions like SelectAwaitWithCancellation need Obsolete attributes so that we can tell the developer how they should change their code.)
In fact, there's no need for these obsolete methods still to be on AsyncEnumerable in the ref assembly. (They do all need to be there on the runtime assembly to maintain backwards compatibility, and that's how they've also ended up being on the same type in the ref assemblies.) So the fix for this will be to use a different name for the type that defines all these methods that are only still publicly available so that we can ensure that System.Linq.Async stops defining a public AsyncEnumerable type in its ref assemblies.