Skip to content

Overload resolution for GetEnumerator fails with optional parameters #19742

@jskeet

Description

@jskeet

(Originally reported in ECMA standardization; copied here at the suggestion of @MadsTorgersen as it may somewhat fall out of async enumerable work.)

When iterating over a type that has a custom GetEnumerator method, it is claimed that after looking up the method group, the next step (in the C# 5 spec section 8.8.4) is to:

  • Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.

However, that appears not to quite be the case:

using System;
using System.Collections.Generic;

class Test
{
    static void Main(string[] args)
    {
        foreach(var x in new Test()) // error CS1579: foreach statement cannot operate on variables of type 'Test' because 'Test' does not contain a public definition for 'GetEnumerator'
        {
            Console.WriteLine(x);
        }
    }

    public IEnumerator<int> GetEnumerator(int count = 10)
    {
        for (int i = 0; i < count; i++)
        {
            yield return i;
        }
    }
}

Here overload resolution with an empty argument list should be fine - I can call new Test().GetEnumerator(). There isn't an empty parameter list, but that's not the same thing.

(The same problem occurs for params int[] values, so we've actually had an issue since C# 1.0!)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions