re-motion mixins basics -- overriding target methods

Since a target class is not necessarily designed to be extended by a mixin class, a mixin class might have better ideas on how to implement properties
and methods in the target class. In our example, the FloorWaxMixin might desire to override the target class' TasteGood method to a more floorwaxy slogan, like "Luster AND flavor – here comes the dessert wax!".

You achieve this by attributing the mixin's implementation of the member to override with OverrideTarget. This requires that the method to override is virtual – just as in plain old inheritance.

public class DessertTopping
{
  public virtual void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm, tastes terrific!");
  }
}

[Extends (typeof (DessertTopping))]
public class FloorWaxMixin : IFloorWaxMixin
{
  public void SealFloor ()
  {
    Console.WriteLine ("Luster AND flavor -- here comes the dessert wax!");
  }

  [OverrideTarget]
  public void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm... the yummiest floor-wax ever!");
  }
}

Most re-motion mixin will work regardless of who extends whom, and this code is no exception. You can use the OverrideTarget attribute if you extend with the Uses attribute instead of the Extends attribute:

[Uses (typeof (FloorWaxMixin))]
public class DessertTopping
{
  // must be 'virtual' now, so that the mixin can override it
  public virtual void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm, tastes terrific!");
  }
}

public class FloorWaxMixin : IFloorWaxMixin
{
  public void SealFloor ()
  {
    Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
  }

  [OverrideTarget]
  public void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm... the yummiest floor-wax ever!");
  }
}
Target overrides Mixin?

In re-motion mixins, not only can mixin classes override members in the target class, it also works the other way around. This is easy to demonstrate in a toy example and will pose no surprises. Let's say, we want that DessertTopping overrides FloorWax's SealFloor. The following code will NOT work, because the OverrideMixin attribute requires that the mixin class is derived from the generic type Mixin<TThis>, and we have not covered that yet in this tutorial.

// *** bad sample code ***
// *** won't work      ***
[Uses (typeof (FloorWaxMixin))]
public class DessertTopping
{
  public virtual void TasteGood ()
  {
    Console.WriteLine ("Mmmmmm, tastes terrific!");
  }

  [OverrideMixin]
  public virtual void SealFloor ()
  {
    Console.WriteLine ("You can also seal the floor with it!");
  }
}

public class FloorWaxMixin : IFloorWaxMixin
{
  public virtual void SealFloor ()
  {
    Console.WriteLine ("Dirt, grime, even black heel marks -- wipe clean with a damp mop!");
  }
}

Apart from the fact that the listing above won't work, alert readers might observe that this example makes very little sense – even in the make-believe world of contrived toy examples this is a bit of a stretch. If DessertTopping has a SealFloor method, isn't it a dessert wax already? Why use a mixin in first place?

We will return to the question of overriding mixin methods in section re-motion mixins basics -- overriding mixin methods, after introducing the generic Mixin<TThis> and Mixin<TThis, TBase> types.

Sample code

The sample code for this section is stored in subversion