Simone
Simone

Reputation: 1337

Base class in C#... that can be inherited from like an interface?

I need to implement a basic behaviour for many classes. To make an example, let's say it is a sort of drawing behaviour: there are many different type of objects that may be drawn, and they all need a few attributes and some common code to implement the drawing process. Let's say I put this common part in a class called Drawable.

The problem is that these different classes may well be extending other classes, so I can't have them inherit from Drawable. The obvious solution would be using an interface (IDrawable), but then I couldn't implement any code in it; another solution I can think of would use composition, by creating a DrawAction class that all of my classes would instantiate, but this would require me to put the same code (if just a couple of lines) in all the classes that I need to make drawable.

Can someone please give me suggestions on how to do this? Thanks.

Upvotes: 2

Views: 1690

Answers (5)

Phill_P
Phill_P

Reputation: 399

It sounds like the Decorator pattern may be appropriate for what you are trying to achieve.

See Decorator Pattern Wikipedia entry

  • Instead of trying to inherit the common "Drawing" logic, place the common logic in another class ie, a "Draw*er*"
  • When an object must be drawn, pass it to the appropriate Draw*er* (or make a Draw*er* for it)
  • You may still find an IDrawable interface useful so that the Draw*er* code can be written against a known interface.
  • You may end up with multiple Draw*er* implementations (in which case you will need to handle dynamic selection of the appropriate Drawer for each object to be drawn)

Upvotes: 1

Salvatore Previti
Salvatore Previti

Reputation: 9070

C# doesn't supports multiple inheritance. Stop. You cannot do that. You are talking about "Mixins"... that are still not supported in C#.

However there are several alternatives you can use.

The simpler one is to use a Mixin class that you can add as a field in all your classes. For example...

public class DrawerMixin
{
    public void DrawRectangle() { ... }
}

public class MyClass1 : Component
{
    public DrawerMixin Drawer { get; private set; }

    public MyClass1()
    {
        this.Drawer = new DrawerMixin(this);
    }

    public MyClass1(DrawerMixin drawer)
    {
        this.Drawer = drawer;
    }

    public void MyFunc()
    {
        ...
        this.Drawer.DrawRectangle();
    }
}

Upvotes: 1

Adam Rackis
Adam Rackis

Reputation: 83366

This may be a situation for composition, rather than inheritance.

You could implement the drawing behavior in one class, and then have all the classes that need it maintain a reference to it.

If you need to support many different drawing algorithms, you might want to look at the Strategy Pattern. Here you would implement many different drawing algorithms, all implementing some sort of interface, and the object that needs to draw would have a reference to one of them.

Depending on your situation, if certain types of objects always need a certain type of drawing algorithm, the selection of which drawing class could be automated with the use of an IoC container, like StructureMap or Unity.

Here's an example of the strategy pattern from DoFactory

Upvotes: 4

Steven
Steven

Reputation: 172786

You can create extension methods for IDrawable:

public static class DrawableExtensions
{
    public static int CalculateSize(this IDrawable drawable)
    {
         return drawable.Width * drawable.Height;
    }
}

This way these methoda apear to be on the IDrawable interface:

IDrawable d = new Circle();

int size = d.CalculateSize();

The downside is that extension methods are static and you can't override them.

Upvotes: 2

sll
sll

Reputation: 62544

You can create instance of DrawAction class and then just inject it into other classes using constructor dependency injection rather than explicitly instantiating it by each class, this give you less coupled design as well:

IDrawAction drawAction = new DrawAction();
var drawable = new Drawable(drawAction);

public class Drawable
{
    public Drawable(IDrawAction drawAction)
    {
    }
}

Upvotes: 5

Related Questions