Skip to content

Async-streams: allow pattern-based await foreach to use extension methods #32289

@jcouv

Description

@jcouv

Previously, we thought this would be handled by the general feature of allowing pattern-based foreach to use extension methods. But that was split into a separate feature (hopefully still candidate for 8.0).

Even if we don't do it for regular foreach, LDM wants to do this for await foreach.
And when we do it, the order should be: (1) instance method, (2) interface, (3) extension method.
That order matches the behavior we want for foreach and we also think it is sensible in general.

From LDM 1/9.

        [Fact]
        public void TestGetAsyncEnumeratorPatternViaExtensions()
        {
            string source = @"
public class C
{
    async System.Threading.Tasks.Task M()
    {
        await foreach (var i in new C())
        {
        }
    }
    public sealed class Enumerator
    {
    }
}
public static class Extensions
{
    public static C.Enumerator GetAsyncEnumerator(this C c)
    {
        throw null;
    }
}";
            var comp = CreateCompilationWithMscorlib46(source);
            comp.VerifyDiagnostics(
                // (6,33): error CS8411: Async foreach statement cannot operate on variables of type 'C' because 'C' does not contain a public definition for 'GetAsyncEnumerator'
                //         await foreach (var i in new C())
                Diagnostic(ErrorCode.ERR_AwaitForEachMissingMember, "new C()").WithArguments("C", "GetAsyncEnumerator").WithLocation(6, 33)
                );
        }

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions