3

In Wagner's "Effective C#," item 23, he explains that

interface methods are not virtual...they are a declaration of a concrete implementation.

I find that to be a conundrum, because it means that interface methods represent early binding, and yet they have the behavior of late-binding. It rouses curiosity of how they work under the covers. In C++ this would turn into a discussion of vtables. In C#, I don't know what it turns into. Can someone spell it out?

p.s. This question has a cousin, but this question focuses on interfaces.
p.p.s. Please don't worry about "you don't need to know how it works." Again, this is about curiosity.

Community
  • 1
  • 1
Brent Arias
  • 29,277
  • 40
  • 133
  • 234

1 Answers1

6

Right, they are not virtual from the language point of view. But they actually are as far as the CLR is concerned. This sample code:

class Example : IDisposable {
    public void Dispose() {}
}

Produces this IL for the Dispose() method:

.method public hidebysig newslot virtual final    // <=== here
        instance void  Dispose() cil managed
{
  // Unimportant
} // end of method Example::Dispose

Note the attributes on the method: virtual and final. The final is what ensures that you can't override the method in a derived class. Making the interface method implementation behave like a non-virtual method in the language but a virtual one at runtime.

This then also answers your question about early/late binding. It's early, the v-table slot is filled in when the class is loaded.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Clearly your post is my answer. There is just one detail. You say an interface represents early binding, but it certainly exhibits late binding: `foreach(IMyInterface foo in Yahoo) foo.Run();`. In this case, determining which `Run` method to call must occur well-after the class is loaded, yes? How is that not late-binding? – Brent Arias Nov 17 '10 at 21:34
  • 1
    @Brent Arias - It depends on your definition of "late binding". See http://stackoverflow.com/questions/3842102/c-polymorphism/3842173#3842173 – Jeffrey L Whitledge Nov 17 '10 at 21:51
  • 1
    No, that's early bound. The call can be made without having to search through a list of possible candidate methods. Late binding has a well defined meaning, in C# it involves the *dynamic* keyword or System.Reflection. Key point about interface method calls is that they are *always* indirect calls (callvirt), never a direct call. Even though the language says that they are not virtual. (I'll avoid mentioning that C# uses callvirt even on non-virtual methods to get the cheap null check). – Hans Passant Nov 17 '10 at 21:51