csharpstandard icon indicating copy to clipboard operation
csharpstandard copied to clipboard

Example in 18.4.6 is incorrect: calling an ambiguous-looking interface member can work...

Open jskeet opened this issue 3 months ago • 5 comments

We have the following example in 18.4.6 (which isn't tested as it's marked for "needs review"):

interface IList
{
    int Count { get; set; }
}

interface ICounter
{
    void Count(int i);
}

interface IListCounter : IList, ICounter {}

class C
{
    void Test(IListCounter x)
    {
        x.Count(1);             // Error
        x.Count = 1;            // Error: cannot assign to a method group
        ((IList)x).Count = 1;   // Ok, invokes IList.Count.set
        ((ICounter)x).Count(1); // Ok, invokes ICounter.Count
    }
}

With text:

In the following code [...] the first two statements cause compile-time errors because the member lookup (§12.5) of Count in IListCounter is ambiguous.

However, the first of these statements works when running the example tester. It's only the second which fails (CS1656: Cannot assign to 'Count' because it is a 'method group').

Has interface member lookup changed in a way that has made the first statement become valid, or has the spec always just been wrong?

jskeet avatar Mar 27 '24 10:03 jskeet

Interestingly, if the type of the Count property in IList is changed to Action<int> Count { get; set; }, then it still doesn't complain even though x.Count(1) could either be a method invocation or a property access followed by a delegate invocation.

jskeet avatar Mar 27 '24 10:03 jskeet

FWIW, "Microsoft (R) Visual C# Compiler version 4.8.9037.0 for C# 5" warns about the ambiguity:

Class1.cs(18,11): warning CS0467: Ambiguity between method 'ICounter.Count(int)' and non-method 'IList.Count'. Using method group.
Class1.cs(8,10): (Location of symbol related to previous warning)
Class1.cs(3,9): (Location of symbol related to previous warning)
Class1.cs(18,9): error CS1656: Cannot assign to 'Count' because it is a 'method group'

Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610) doesn't. Roslyn source code has it commented out: https://github.com/dotnet/roslyn/blob/958f2354c4d83dbb0e7723d0a8079a0dfbc33f25/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs#L321

git grep -e WRN_AmbigLookupMeth 3611ed35610793e814c8aa25715aa582ec08a8b6 shows no public version of Roslyn has issued this warning.

KalleOlaviNiemitalo avatar Mar 27 '24 11:03 KalleOlaviNiemitalo

Thanks for digging, @KalleOlaviNiemitalo! Will see whether @ericlippert remembers the details...

jskeet avatar Mar 27 '24 11:03 jskeet

Microsoft's warning CS0467 documentation doesn't mention this being obsolete, and includes almost the same IListCounter example.

KalleOlaviNiemitalo avatar Mar 27 '24 11:03 KalleOlaviNiemitalo

We believe there is a specified preference for methods when performing member lookup of "something that looks like an invocation". I will try to find it.

jskeet avatar Mar 27 '24 21:03 jskeet