Interfaces can't hide parent interfaces entirely, but the implementing class can, which can be useful.
Consider a class MyStringList
which is a read-only list that implements IList<string>
. We'll have it as a simple pass-through for simplicity: Some of the members are rather pointless, so we can do as follows:
//implement this one implicitly, as it's useful.
public int Count
{
return _list.Count;
}
//do a half-and-half on the indexer
public string this[int index]
{
get
{
return _list[index];
}
}
string IList<string>.this[int index]
{
get
{
return this[index];
}
set
{
throw new NotSupportedException("Collection is read-only.");
}
}
//hide some pointless ones.
bool ICollection<string>.IsReadOnly
{
get
{
return true;
}
}
void IList<string>.Insert(int index, string item)
{
throw new NotSupportedException("Collection is read-only.");
}
void IList<string>.RemoveAt(int index)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<string>.Add(string item)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<string>.Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
bool ICollection<string>.Remove(string item)
{
throw new NotSupportedException("Collection is read-only.");
}
Someone dealing with the MyStringList
through IList<string>
interface has to be able to call these pointless members, but there's no need for someone dealing with the MyStringList
to do so.
Now, with this possible for the class, an interface can force such an implication onto the class by name-matching a parent interface. The class example is IEnumberable<T>
where the GetEnumerator()
matches that of IEnumerable
from which it inherits. Hence the class can implicitly implement only one, and must hide the other or both (since one can always cast the result (an IEnumerator<T>
) to the result-type of the other (an IEnumerator
) then the most sensible behaviour is generally to implicitly implement the IEnumberable<T>
version, and explicitly implement the IEnumerable
one (normally by returning the result of the other).
However, while the hiding forces at least one to be hidden, there's nothing to force that particular choice as to which (if any) is implicitly implemented, beyond one having so obvious an advantage over the other that few would do otherwise.