-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
The LINQ specification expands:
from T t in sourceto use source.Cast<T>().
For Enumerable.Cast<T>, this works because the source is a non-generic IEnumerable, and thus there's only the one generic type parameter for the result.
For AsyncEnumerable.Cast, this falls down. Such a Cast extension method today needs to be generic on both the TSource and TResult, e.g.
public static IAsyncEnumerable<TResult> Cast<TSource, TResult>(this IAsyncEnumerable<TSource> source)and the C# compiler refuses to bind the from cast syntax when the arity of Cast doesn't match.
I was expecting extension everything would fix this, e.g.
extension<TSource>(IAsyncEnumerable<TSource> source)
{
public IAsyncEnumerable<TResult> Cast<TResult>() { ... }
}but unfortunately it doesn't. While I can write the above, it doesn't provide any expressive power that didn't already exist with extension methods today, because the resulting method still has a generic arity of 2, and I still need to provide both type arguments in order to use it, e.g.
IAsyncEnumerable<Base> source = ...;
var result = source.Cast<Base, Derived>();and the C# compiler refuses to use it to satisfy Cast.
IAsyncEnumerable<Derived> results1 = from x in source // OK
select (Derived)x;
IAsyncEnumerable<Derived> results2 = from Derived x in source // Error!!
select x;cc: @jcouv, @MadsTorgersen