views:

159

answers:

5

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 the property, so I can see how it could be used.

Is there any practical reason to hide members in interfaces which implement other interfaces? For example consider the example below. IChildInterface implements IParentInterface, and hides PropertyA.

interface IParentInterface
{
    string Name { get; set; }
    int PropertyA { get; set; }
    int PropertyB { get; set; }
}

interface IChildInterface : IParentInterface
{
    int PropertyA { get; set; }
    int PropertyC { get; set; }
}
+1  A: 

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: http://stackoverflow.com/questions/3240279/is-there-ever-a-situation-where-derived-class-should-hide

dthorpe
I agree when it comes to classes (including on the exception you give) but I think it's different when it comes to interfaces.
Jon Hanna
A: 

I suppose if you were going to implement IChildInterface explicitly there might be a case where you'd want to hid PropertyA (maybe?)

taylonr
But since IChildInterface implements IParentInterface wouldn't any implementions of IChildInterface (implicit or explicit) also implement IParentInterface?
Eric Anastas
Yeah, I guess now that I think about it, you're probably right.
taylonr
+2  A: 

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.

Jon Hanna
+10  A: 

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

Eric Lippert
+1  A: 

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; }
}
theburningmonk