csharpstandard
csharpstandard copied to clipboard
Example in 18.4.6 is incorrect: calling an ambiguous-looking interface member can work...
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
inIListCounter
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?
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.
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.
Thanks for digging, @KalleOlaviNiemitalo! Will see whether @ericlippert remembers the details...
Microsoft's warning CS0467 documentation doesn't mention this being obsolete, and includes almost the same IListCounter example.
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.