Reputation: 45947
Coming from here i have something equal in my code. Let's say i have the following class:
public class EList<T> : List<T>
{
public string Add { get; set; }
}
now i'm expecting the error
Ambiguity between 'EList.Add' and 'EList.Add(int)'
but the following code works without any errors:
EList<int> il = new EList<int>();
il.Add(1);
il.Add = "test";
Question: Does inheritance suppress this error by mistake?
Upvotes: 4
Views: 1725
Reputation: 239694
It's explicitly catered for within the member lookup rules of C# (C# Specification section 7.4). Specifically, what matters here is invocability
skipping earlier rules
Next, if the member is invoked, all non-invocable members are removed from the set. (The call to
Add()
is invoked. Therefore theAdd
property is removed from the set)Next, members that are hidden by other members are removed from the set. For every member S.M in the set, where S is the type in which the member M is declared, the following rules are applied:
- If M is a constant, field, property, event, or enumeration member, then all members declared in a base type of S are removed from the set. (The
Add
method in the base type is removed)more rules
So at this point, no ambiguity since the above two rules have eliminated one or other of the potentially conflicting members.
See also section 10.3, Class members:
The name of a constant, field, property, event, or type must differ from the names of all other members declared in the same class.
The name of a method must differ from the names of all other non-methods declared in the same class. In addition ...
(My emphasis)
And,
The inherited members of a class type (§10.3.3) are not part of the declaration space of a class. Thus, a derived class is allowed to declare a member with the same name or signature as an inherited member
Upvotes: 4
Reputation: 2453
There is no ambiguity here as the Add property is defined in child class but the Add method is there in your parent class. The ambiguity is only there if you have members with same name within the same class. Here the object you have created is of type EList
and you are referring it by a variable of type EList
so the compiler knows that there is one Add method defined which is in your parent class.Same case with the Add
property also.
Even if you have defined another Add
method in EList
there wont be any error just a warning stating that you are hiding an already implemented member from your base class.
This gives a more detailed info MSDN
The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. Then perform overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected.
Upvotes: 2
Reputation: 2300
Your code actually gives a warning:
Warning CS0108 'EList.Add' hides inherited member 'List.Add(T)'. Use the new keyword if hiding was intended.
There's no ambiguity here. il.Add(1);
(because of ()
) is a method call. So compiler looks for method named Add
. il.Add = "test";
(because of =
) is properties setter call. So compiler looks for property named Add
.
So it seems that Add
property override Add
method. And then il.Add(1);
and il.Add = "test";
calls select best matching solution.
Upvotes: 2