(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!)
(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
GetEnumeratormethod, it is claimed that after looking up the method group, the next step (in the C# 5 spec section 8.8.4) is to:However, that appears not to quite be the case:
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!)