Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

interface inheriting multiple interfaces: how is this handled by a C# compiler?

Recently I found out that C# allows for

An interface can inherit from one or more base interfaces.

For instance, the IScreen in Caliburn.Micro does this in http://caliburnmicro.codeplex.com/SourceControl/latest#src/Caliburn.Micro/IScreen.cs

namespace Caliburn.Micro
{
    public interface IScreen : IHaveDisplayName, IActivate, IDeactivate, 
        IGuardClose, INotifyPropertyChangedEx
    {
    }
}

I get why this is useful, as it implies that a class implementing IScreen also needs to implement the other interfaces.

But I wonder how the C# handles that compiler and run-time wise.

A little background/context of this question:

I come from a background where interfaces define a method-table, and that classes implementing interfaces have both their own method table, and pointers to the method tables of the interfaces they implement.

Sub questions swirling my mind stem from various multiple class inheritance discussions I had with people in the past, of which I think they apply to this case as well:

  • Having an interface be able to inherit from multiple base interfaces, how would the order of methods in that table be?
  • What if those interfaces have common ancestors: would those methods appear multiple times in the table?
  • What if those interfaces have different ancestors, but similar method names?

(I'm using the word methods here, implying that a property defined in an interface will have a get_ or set_ method).

Any insight into this is much appreciated, as well as tips on how to phrase this question better.

like image 979
Jeroen Wiert Pluimers Avatar asked Nov 14 '13 10:11

Jeroen Wiert Pluimers


1 Answers

First of all, let's be explicit in saying that "interface inheritance" is not quite the same thing as class-based inheritance (and using the word "inheritance" for both is perhaps misleading).

That's because interfaces cannot be instantiated on their own, so the compiler/runtime pair does not have to keep track of how to make a virtual call for standalone interface types (e.g. you don't need to know how to call IEnumerable.GetEnumerator -- you just need to know how to call it on a specific type of object). That allows for handling things differently at compile time.

Now I don't actually know how the compiler implements "interface inheritance", but here's how it could be doing it:

Having an interface be able to inherit from multiple base interfaces, how would the order of methods in that table be?

It's not necessary for the "derived" interface to have a method table that includes the methods from all of its ancestor interfaces because it does not actually implement any of them. It's enough for each interface type to only have a table of methods it defines itself.

What if those interfaces have common ancestors: would those methods appear multiple times in the table?

Given the answer to the previous question, no. In the end a concrete type will only implement IFoo just once, regardless of how many times IFoo appears in the "hierarchy" of implemented interfaces. Methods defined in IFoo will only appear in IFoo's bookkeeping tables.

What if those interfaces have different ancestors, but similar method names?

Again, no problem. You need appropriate syntax to tell the compiler "here's how to implement IFoo.Frob and here's IBar.Frob", but since methods of IFoo and IBar will be mapped in separate tables there are no technical issues.

Of course this leaves the question "how are methods dispatched at runtime?" unanswered. But it's not that difficult to imagine a possible solution: each concrete type C has pointers to one method table per interface it implements. When it's time to make a virtual method call the runtime looks at the concrete type, finds the table for the interface whose method is going to be called (the type of the interface is known statically) and makes the call.

like image 177
Jon Avatar answered Oct 29 '22 01:10

Jon