I understand that a class which inherits from another class may hide a property by using the new
keyword. This, however, is hiding a specific implementation of
Hiding inherited members should never be done deliberately as part of a design. Method hiding is allowed by the language to prevent changes in the ancestor (in major releases of a library) from breaking descendants who happen to already have a member by that same name defined.
That said, sometimes it is convenient to hide an inherited method with an equivalent method that returns a more specific type. In these cases, the only thing you're doing is typecast sugar - be careful not to change the semantics of the method because callers may just as easily call the ancestor method instead of yours.
See also: Is there ever a situation where derived class should hide …?
Is there any practical reason to hide members in interfaces which implement other interfaces?
Sure. The fact that the BCL itself uses this pattern is indicative that the pattern is practical. For example:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
interface IEnumerable<T> : IEnumerable
{
new IEnumerator<T> GetEnumerator();
}
The designers of IEnumerable<T>
wished to be backwards-compatible with IEnumerable
but also wanted to ensure that every usage of GetEnumerator
on the generic interface called the generic version. Hiding is the appropriate mechanism in this case.
For some additional discussion on subtle points about method hiding, see:
http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx
One case I found hiding base member useful is when you have a base interface which exposes a getter on a property but the derived interface wants to expose a setter:
public interface IBase
{
int MyProperty { get; }
}
public interface IDerive : IBase
{
// you need to specify the getter here too
new int MyProperty { get; set; }
}
I suppose if you were going to implement IChildInterface explicitly there might be a case where you'd want to hid PropertyA (maybe?)
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.