Common Type System—Interface Reimplementation


Jump to: navigation, search
Visual C# Tutorials
.NET Framework Tutorials

Common Type System

© 2006 Wiley Publishing Inc.

Interface Reimplementation

You can generally prevent subclasses from redefining a method by marking methods as final (or not making them virtual in the first place). A subclass can always mark their method as newslot and provide a new method that matches an existing method’s signature. But when a virtual call is made to the base type’s version, this new definition won’t be dispatched to. This is because the vtable differentiates between the two—in other words, it creates a new slot for both.

However, with interfaces, there is only a single interface map per interface for any given type. This means that calling through the interface map always goes to the furthest derived version, regardless of whether subclasses have defined their own implementations as final or virtual. This can be surprising.

For example, consider the base and subclass:

class FooBase : IFoo
{
   public void Foo()
   {
      Console.WriteLine(“FooBase::Foo);
   }
 
   public void Bar()
   {
      Console.WriteLine(“FooBase::Bar);
   }
}
 
class FooDerived : FooBase, IFoo
{
   public new void Foo()
   {
      Console.WriteLine(“FooDerived:Foo”);
   }
 
   public new void Bar()
   {
      Console.WriteLine(“FooDerived::Bar);
   }
}

If you wrote some code that called Foo and Bar in different ways, you might or might not be surprised at the results. When looked at in totality, they make intuitive sense. But a lot of people are still surprised that a type can completely redefine a base type’s implementation of an interface although the initial implementation was protected.

FooDerived d = new FooDerived();
FooBase b = d;
IFoo i = d;
 
b.Foo(); // Prints "FooBase::Foo"
b.Bar(); // Prints "FooBase::Bar"
 
d.Foo(); // Prints "FooDerived::Foo"
d.Bar(); // Prints "FooDerived::Bar"
 
i.Foo(); // Prints "FooDerived::Foo" 


Previous_Page_.gif Next_Page_.gif





Personal tools