7

I have two classes :

public class Question : IDisposable, IEquatable<Question>
{
}

public class SessionQuestion : Question, IDisposable, IEquatable<SessionQuestion>
{
}

As Question inherits IDisposable and IEquatable, does SessionQuestion implicitly inherit those interfaces as well?

bytecode77
  • 14,163
  • 30
  • 110
  • 141
Will
  • 3,413
  • 7
  • 50
  • 107
  • Yup. Try yourself, do `SessionQuestion s = new SessionQuestion();` then `if (s is IDisposable)` – dmeglio Aug 15 '15 at 21:33
  • 3
    Attention: Not that you get confused. Due to inheritance, *SessionQuestion* inherits `IEquatable` from *Question*. However, *SessionQuestion* also implements `IEquatable`, which is a different interface than `IEquatable`. Thus, you could omit specifying the *IDisposable* interface for *SessionQuestion* (it is inherited from *Question*), but you would need to keep `IEquatable` (as this interface is not implemented by *Question*) –  Aug 15 '15 at 21:33
  • @elgonzo excellent point! – dmeglio Aug 15 '15 at 21:34
  • http://stackoverflow.com/questions/32029791/how-can-i-properly-override-a-class-method-property-in-a-derived-class as a follow up question. Thanks for the help. – Will Aug 15 '15 at 21:59
  • @Will, i just extended my answer to illustrate some weird and entertaining gotchas than can happen when a class inherits an interface from its base class while at the same time providing some explicit implementations of members of that interface. Enjoy :-D –  Aug 15 '15 at 22:43
  • 1
    @elgonzo is right. But note that implementing `IEquatable<>` on a `class` that is not `sealed` may be a bad idea. See [Should IEquatable, IComparable be implemented on non-sealed classes?](http://stackoverflow.com/questions/1868316/) for more. – Jeppe Stig Nielsen Aug 15 '15 at 23:38

3 Answers3

6

The answer is "Yes" -- interfaces are inherited. However, whether you can omit including interface definitions from a class depends on whether that class wants to have certain interface members as explicit interface implementations.

Let's take this very simple (and silly) example:

public interface IMyInterface
{
    void foo();
}

public class A : IMyInterface
{
    public void foo()
    {
        Console.Out.WriteLine("A.foo() executed");
    }
}

public class B : A, IMyInterface
{
    void IMyInterface.foo()
    {
        Console.Out.WriteLine("B.foo() executed");
    }
}

Since B wants to have the foo() method as an explicit interface implementation, the IMyInterface interface has to be specified as part of its class definition -- even if class A already implements this interface. Inheriting an interface declaration from a base class is not sufficient in this case.

If class B would not have explicit interface implementations, then class B does not need to specify the interface (IMyInterface in this little example) again.


Inheriting an interface from a base class and having some explicit interface implementation for members of that interface can lead to effects which can be surprising at best, and at worst can lead to broken/buggy software.

If you execute the following code sequence:

A obj = new A();
obj.foo();
IMyInterface x = obj;
x.foo();

the output will be

A.foo() executed
A.foo() executed


However, let's now use an object of type B but otherwise keep the code exactly the same:

B obj = new B();
obj.foo();
IMyInterface x = obj;
x.foo();

the output will be somewhat different:

A.foo() executed
B.foo() executed

Why is that so? Remember that class B inherits the implementation of the foo() method from class A. Thus, calling obj.foo() will still execute the inherited foo() method.

Now, why is then x.foo() not invoking the foo() implementation provided by class A as well? Or, why is obj.foo() not invoking the implementation given for foo() in class B?

Because x is a variable of type IMyInterface, thus the explicit interface implementation of the foo() method provided by the object of type B takes precedence when invoking x.foo(). The variable obj is not of type IMyInterface, hence obj.foo() will not invoke the explicit interface implementation of the foo() method.

Because of these surprising results it is easy to understand why explicit interface implementations for interfaces which are already implemented by a base class is really a bad idea in most cases. As the saying goes: Just because you can does not mean you should.

  • 1
    The technical term here is [Interface re-implementation](https://msdn.microsoft.com/en-us/library/aa664594.aspx). A less confusing alternative to it may be to implement an interface in a base class by a `public` ***`virtual`*** method/property/etc. – Jeppe Stig Nielsen Aug 15 '15 at 23:45
3

Of course.

In fact, the .NET Framework is not at all a flat class hierachy. Pick a random class and take a look. You'll see that it derives a class that derives a class that..., and so on.

Interfaces are also inherited to grand children, just like normal classes are.

And as for members you have to implement: If you implemented them in Question, you don't need to implement them in SessionQuestion, of course.

bytecode77
  • 14,163
  • 30
  • 110
  • 141
3

Of course, you'll still need to implement all the members that the interfaces define. However, if the base class contains a member that matches an interface member, the base class member can work as the implementation of the interface member and you are not required to manually implement it again.

Maz H
  • 151
  • 8