Remove AsyncEnumerable from System.Linq.Async public API by idg10 · Pull Request #2292 · dotnet/reactive (original) (raw)

Resolves #2291

Earlier previews continued to define an AsyncEnumerable class in System.Linq.Async's public API. This is OK for extension methods—the compiler doesn't mind if multiple identically-named classes exist and they all provide extension methods for the same interface, as long as there's no ambiguity as to which particular method is being used.

However, this caused direct invocation of static methods such as AsyncEnumerable.Range(1, 10) to fail. Even though System.Linq.Async no longer defines this method, the compiler still reports an ambiguity error. And that's because even though there's only one AsyncEnumerable.Range, there were two AsyncEnumerable classes. (The one in System.Linq.Async, and the new one in System.Linq.AsyncEnumerable.)

We need to retain AsyncEnumerable in the runtime assemblies for binary compatibility. But in the public-facing API, the only reason we were continuing to define this type was so we could apply [Obsolete] attributes to the AsyncEnumerable extension methods that have been replaced by something else (e.g. because names have changed), or that are being removed entirely (in the case of ToEnumerable, which should never have existed). This now puts those on a new AsyncEnumerableDeprecated class in the public-facing API.

(Unfortunately, AsyncEnumerable.Create is a casualty of this. It was the one non-extension public static method previously defined by AsyncEnumerable that didn't move into System.Linq.AsyncEnumerable. It's available as AsyncEnumerableEx.Create now in System.Interactive.Async, but it's not possible for us to provide an obsolete attribute that tells people this. Fortunately the method shouldn't really be used much because since .NET Core 3.0, language-level support for async iterators provides a better solution to the problem this method solves.)