Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jskeet opened this issue Mar 27, 2024 · 5 comments
Assignees
Labels
type: bug The Standard does not describe the language as intended or implemented

Comments

@jskeet
Copy link
Contributor

jskeet commented Mar 27, 2024

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 jskeet changed the title Example in 18.4.6 is incorrect Example in 18.4.6 is incorrect: calling an ambiguous-looking interface member can work... Mar 27, 2024
@jskeet
Copy link
Contributor Author

jskeet commented Mar 27, 2024

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 jskeet added meeting: discuss This issue should be discussed at the next TC49-TG2 meeting type: bug The Standard does not describe the language as intended or implemented labels Mar 27, 2024
@KalleOlaviNiemitalo
Copy link
Contributor

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.

@jskeet
Copy link
Contributor Author

jskeet commented Mar 27, 2024

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

@KalleOlaviNiemitalo
Copy link
Contributor

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

@jskeet
Copy link
Contributor Author

jskeet commented Mar 27, 2024

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 jskeet self-assigned this Mar 27, 2024
@jskeet jskeet removed the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug The Standard does not describe the language as intended or implemented
Projects
None yet
Development

No branches or pull requests

2 participants