Skip to content

System.Linq.Async v7 causes ambiguity errors for non-extension methods #2291

@idg10

Description

@idg10

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions