views:

534

answers:

4

I come from a C++ background where I can use template mixins to write code that refers to FinalClass which is a template parameter that is passed in. This allows reusable functions to be "mixed-in" to any derived class, by simply inheriting from ReusableMixin with a template paramter of MyFinalClass. This all gets inlined into the class so it's as though I just wrote a big class that did everything -- ie very fast! Since mixins can chain, I can mix-in all sorts of behaviour (and state) into one object.

If anyone wants clarification on the technique, please ask. My question is, how can I get reuse like that in C#? Note: C# generics don't allow inheriting from a generic parameter.

A: 

Would extension methods help in your scenario?

Daniel O
i don't think so, don't I have to specify the class that I'm extending, so I can't apply them to a whole pile of classes... I don't know much about them though, do you?
Jesse Pepper
The problem with an extension method is that it's just syntactic sugar. The method only has access to the public (or internal if in the same assembly) interface of the class. Also, it will only be visible to the user of the class if the remember to include the namespace of the extension method.
Andrew Kennan
+4  A: 

In C#, the closest you get to C++ style mixins is adding the mixins as fields of a class and add a bunch of forwarding methods to the class:

public class MyClass
{
    private readonly Mixin1 mixin1 = new Mixin1();
    private readonly Mixin2 mixin2 = new Mixin2();

    public int Property1
    {
        get { return this.mixin1.Property1; }
        set { this.mixin1.Property1 = value; }
    }

    public void Do1()
    {
        this.mixin2.Do2();
    }
}

This is usually enough, if you only want to import functionality & state of the mixins. A mixin can of course be implemented as you like, complete with (private) fields, properties, methods, etc.

If your class also needs to express "is-a" relationships with the mixins then you need to do the following:

interface IMixin1
{
    int Property1 { get; set; }
}

interface IMixin2
{
    void Do2();
}

class MyClass : IMixin1, IMixin2
{
    // implementation same as before
}

(This is also the standard way how multiple inheritance is emulated in C#.)

Of course, the mixin interfaces as well as the mixin classes can be generics, e.g. with a most-derived class parameter or whatever.

Andreas Huber
but what about if you want to mix in state?
Jesse Pepper
I've modified the answer accordingly, HTH.
Andreas Huber
hmmm... it seems ok. One of the best uses of mixins is to implement an interface for you, so it's quite painful to have to manually write each method. I don't know if you've convinced me to prefer C#, but you thanks for your answer!
Jesse Pepper
+10  A: 

You could use interfaces and extension methods. For example:

public interface MDoSomething // Where M is akin to I
{
     // Don't really need any implementation
}

public static class MDoSomethingImplementation
{
     public static string DoSomething(this MDoSomething @this, string bar) { /* TODO */ }
}

Now you can use the mixins by inheriting from MDoSomething. Remember, using extension methods inside (this) class requires the this qualifier. For example:

public class MixedIn : MDoSomething
{
    public string DoSomethingGreat(string greatness)
    {
         // NB: this is used here.
         return this.DoSomething(greatness) + " is great.";
    }
}

public class Program
{
    public static void Main()
    {
        MixedIn m = new MixedIn();
        Console.WriteLine(m.DoSomething("SO"));
        Console.WriteLine(m.DoSomethingGreat("SO"));
        Console.ReadLine();
    }
}

HTH.

Jonathan C Dickinson
Cool and definitely true - I've done this many times +1
Dario
A: 

In C#, you can use the "partial" keyword to indicate that your class is implemented in multiple source files. You can then use a little templating tool to auto-generate additional source code files that contain the methods you want to inject in your class.

The T4 templating tool included in Visual Studio can be used to do that, but a more simplistic approach can be used. See my own templating engine: http://myxin.codeplex.com/

Stephan Leclercq