Introduction to Mixins For the C# Developer

If you are a C# developer then you may keep hearing about all the cool kids from Smalltalk, Ruby, Python, Scala using these crazy things called mixins. You may even be a little jealous, not because you want the feature, but because they have a feature with an awesome name like "mixin". The name is pretty sweet. And in fact, it is fairly self-explanatory since mixins are all about "mixing-in behaviors".

It is actually an Aspect Oriented Programming (AOP) term which is defined by wikipedia as:

A mixin is a class that provides a certain functionality to be inherited by a subclass, but is not meant to stand alone. Inheriting from a mixin is not a form of specialization but is rather a means to collect functionality. A class may inherit most or all of its functionality by inheriting from one or more mixins through multiple inheritance.

No wonder people are confused! That isn’t exactly clear. So let’s try to clear it up just a tiny bit…

Let’s say that we have a C# class that looks like this:

public class Person{
    public string Name { get; set; }
    public int Age { get; set; }
}

Looks good. And we have another C# class that looks like this:

public class Car{
    public string Make { get; set; }
    public string Model { get; set; }
}

Mmmmkay. These classes obviously don’t have anything to do with one another, and hopefully they aren’t in the same object hierarchy. What if we need to do something like, say, serialize to XML? In .NET we would normally decorate the type with a SerializableAttribute and then we would fire up an instance of the XmlSerializer by abstracting it into a method like this:

public static string SerializeToXml(Object obj)
{
    var xmlSerializer = new XmlSerializer(obj.GetType());
    using (var memoryStream = new MemoryStream())
    {
        using (var xmlWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false)))
        {
            xmlSerializer.Serialize(xmlWriter, obj);
        }
        return Encoding.UTF8.GetString(memoryStream.GetBuffer());
    }
}

So now when we need to serialize a class, we can just do this:

string xml = XmlHelper.SerializeToXml(person);

That isn’t too bad, but what if we wanted to do something like this:

string xml = person.SerializeToXml();

In C# 3.0 and later we can introduce an extension method to get exactly that behavior:

public static class XmlExtensions
{
    public static string SerializeToXml(this Object obj)
    {
        var xmlSerializer = new XmlSerializer(obj.GetType());
        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false)))
            {
                xmlSerializer.Serialize(xmlWriter, obj);
            }
            return Encoding.UTF8.GetString(memoryStream.GetBuffer());
        }
    }

}

Now you see what we are doing here, we are creating an extension method on Object so that we can use this on any class. (Well, it really is just a compiler trick, but it "appears" that we have this method on every class) We are performing a very weak form of a mixin, because we now have a similar behavior for any object, even if it doesn’t necessarily have the same inheritance hierarchy. So, why do I say that this is a "weak" mixin? We are sharing behavior across multiple classes, right?

Well, I say it is "weak", but I really should say that it is not a mixin at all because true mixins have state as well as methods. For example, in the above scenario, let’s say we wanted to cache the result of the serialization so that the next time we called it, we would get the same result? This obviously isn’t something you’d want to do unless you had change tracking, but in the C# extension method, this is impossible. There is no way to associate state with the particular instance.

So how do other languages support this behavior? Well, Ruby supports it with a concept called modules which look very similar to classes and allow those modules to be "included" with classes. Ruby even allows you to apply mixins at runtime, which could be a very powerful, albeit potentially confusing, feature. Python solves the problem by allowing multiple inheritance, so I guess you could say that they aren’t really mixins either. It solves all the same problems as mixins though, but it does add a bit of complexity to the implementation (See the Diamond Problem).

In terms of being similar to C#, the Scala solution is the most interesting. Perhaps because Scala is a statically typed and compile-time bound language (for the most part), and so it has some of the hurdles with implementing mixins that C# would face. In Scala the feature is called "traits" and traits can be applied to both classes and instances during construction.

I’m not going to show you the Scala implementation of traits, but what I am going to do is make up a syntax for C# traits so that we can implement the behavior we want above. So first we are going to have to decide on a keyword for this new construct, and I am going to just use the Scala "trait" keyword. In Scala traits look like classes, because that is essentially what they are. They are classes which are not inherited from, but rather "applied" to another class. In fact, traits can even descend from abstract classes.

Nothing Past This Line is Valid C#!

So our C# trait might look something like this:

trait XmlSerializer{
    public string SerializeToXml()
    {
        var xmlSerializer = new XmlSerializer(this.GetType());
        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false)))
            {
                xmlSerializer.Serialize(xmlWriter, this);
            }
            return Encoding.UTF8.GetString(memoryStream.GetBuffer());
        }
    }
}

Neato. We could then take this trait, and apply it to our class like using the "with" keyword:

public class Person with XmlSerializer {
    public string Name { get; set; }
    public int Age { get; set; }
}

Cool, so we have replicated the behavior of the extension method. But now how about that caching? Well, we wouldn’t even need to touch the Person class, we would only have to change the trait:

trait XmlSerializer{
    private string xml;    

    public string SerializeToXml()
    {
        if (String.IsNullOrEmpty(xml)){
            var xmlSerializer = new XmlSerializer(this.GetType());
            using (var memoryStream = new MemoryStream())
            {
                using (var xmlWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false)))
                {
                    xmlSerializer.Serialize(xmlWriter, this);
                }
                xml = Encoding.UTF8.GetString(memoryStream.GetBuffer());            
            }
        }
        return xml;
    }
}

Nice. Now if you think about it, if traits had the ability to support abstract members, then you wouldn’t need interfaces at all, would you? Well, it just so happens that Scala doesn’t have interfaces, and uses traits in this exact capacity. If you declare a mixin with all abstract methods, then have an interface. It becomes even more powerful when you declare mixins with abstract methods that are used by concrete methods that are also declared within the mixin. Head hurting yet? It is some pretty powerful stuff, and should be used as any powerful tool should be, judiciously.

One final note about Scala traits, which I mentioned earlier, is that they can be applied to instances during construction. This is an interesting behavior because it allows individual instances of classes to have a trait applied. If you think about trying to apply an interface at runtime, then you will realize that any trait that you would apply at runtime would have to contain no abstract methods, otherwise you would have no way to tell if the class implemented the methods that were being applied. This is why Scala only allows traits to be applied at construction of an instance, this way Scala can do checking at compile time to determine if the class implements all of the abstract methods that are needed. So, in C# this syntax would look something like this:

var person = new Person() with XmlSerializable;

And if we needed to pass this into a method, we could do this:

public string DoSomething(Person with XmlSerializable person){
    return person.serializeToXml();
}

Very neat stuff.

Mixins and traits are very powerful language constructs which should be used carefully. When used properly they allow us to perform some tasks that OO heirarchies just don’t solve for us. I hope that you learned something from this quick look at a really neat feature in a non-.net language, and I encourage you to look outside of C# in your search for ways to do things better. Whether it be F#, Ruby (or IronRuby), Scala, etc… what is important is that you expand your horizons. Until next time….

Be Sociable, Share!

18 comments

  1. Thank you for the article, Justin.

    The "with trait" seems like an incredibly powerful construct.

    Kindness,

    Dan

  2. Cool stuff. Your writing skills are good, explaining mixins in a very easy-to-understand way.

    Question for you, Justin. You said in the post, [i]"in the C# extension method, this is impossible. There is no way to associate state with the particular instance."[/i]

    I’m not so sure. Seems to me this is *possible*, though a little kludgey.

    Give your example of caching the result of the XML serialization, couldn’t we store this state inside a static Dictionary<object, string> inside the extension method class?

    Kludgey, sure, but does this accomplish the same thing?

  3. @Judah Thanks! And yes, you could store a static dictionary of object/string in that extension class, but that would cause a massive memory leak unless you were very careful to remove the items from the dictionary. I still am not sure that we are really associating state with the instance, merely storing state and using an instance as a key. This can cause many problems though.

    You’d be better off with a Dictionary<WeakReference,String> so that this dictionary doesn’t keep the GC from cleaning up instances that have been placed in it. Then you’d have to periodically go through this dictionary and clean out items that have been garbage collected, otherwise it could grow quickly. And you’d have to put some synchronization around it as well, since you could have multiple threads accessing the dictionary at the same time.

    So yes, you are right, it is not "impossible", it is just a lot of work.

  4. *cough* macros! *cough*

    I don’t mean C or C++ macros (via #define), I mean [i]real[/i] macros, like Lisp (defmacro), Boo Syntactic Macros (http://boo.codehaus.org/Syntactic+Macros) or Nemerle macros (http://nemerle.org/Macros). Using macros you could write a "traits" class (as you specify), and "multiply inherit" from all your traits classes, and the macro would insert your trait members into the class declaration at compile time.

    So macros would allow this exact functionality (and a whole lot more).

    (They would also allow you to completely mutate your language grammar into something that doesn’t resemble C# at all, for good or bad…)

  5. Awesome article, the missing link between abstract classes and interfaces. Someone get on the horn and tell MS to slide this feature into C# 4.0. I have money on the vegas line, 5-1 odds that someone sends you an email complaining that the code above doesn’t compile. :)

  6. @Tony Oh, it has already happened :-)

  7. Very cool article as always. This really gives me some food for thought on a potential technique for an AOP presentation I’m preparing for. Thanks!

  8. Jon von Gillern

    I tried reading about mixins and got really confused. I’m not so confused anymore, thanks Justin.

  9. Have you looked at PostSharp? My understanding is that it brings aspect-oriented programming to C#, but it does require a post-compile step to do the weaving. Not ideal, but from what I’ve heard, it sounds like it works well enough.

  10. i’m slow, and i still feel like things aren’t very clear, all the different connotations of the terms in different languages are all too close for clear understanding. and then i wonder if the whole approach is risky e.g.

    http://www.artima.com/weblogs/viewpost.jsp?thread=246341

    (that’s not me, it is just something i’m trying to grok that is related.)

  11. @justin – even easier if your needs can be met with HttpRuntime.Cache. I just got to play with this today… swap in some generics and you’ve got a quick and dirty cacheing layer.

    [quote]
    using System.Web;
    public static class ExtendsObjects //twss
    {
    public static string CacheSomeBar(this Object o)
    {
    string foo = HttpRuntime.Cache.Get("bar");

    //…

    return foo;
    }

    public static void UncacheSomeBar(this Object o)
    {
    // …

    HttpRuntime.Cache.Remove("bar");
    }
    }
    [/quote]

    it’ll definitely hold state though. "kludgey"? minimally so.

  12. @Justin,
    Thanks for a nice introduction to mixins. I’m .NET developer learning Scala and found it incredible nice and powerful. I’ve read Bill Wagner’s article about mixins in C# before (http://msdn2.microsoft.com/en-us/vcsharp/bb625996.aspx), but you clearly explained that there is no way to fully implement mixins in C#: interfaces do not support state (no members, only methods). This type of things is easy in dynamic languages like JavaScript, but lack of static type-checking is too bad. Scala is the best attempt to bring two worlds together.

  13. I see the utility of mixin lies in its capability to work across class hierarchy, but not for all the classes. In ruby, you can access the attributes, properties in c#, of the class that uses the mixin. So, this makes the mixin more power as it is aware of the class. The module can even call methods. So, you can implement template method for classes without hierarchy.

  14. We’re adding mix-ins to the .NET language Cobra at http://cobra-language.com/. We have basic cases working, but there is still more to do. See http://cobra-language.com/trac/cobra/wiki/MixIn

    Cobra has some other nice features (that are mature) including first class support for unit tests, contracts, dynamic binding and closures.

    Feel free to check it out.

  15. You could do this right now in Boo.

  16. Very good article.

    You might be interested that now there is an open source library available on codeplex that brings mixins to .NET

    For more information checkout http://remix.codeplex.com

    Thank you!

  17. Good introduction. But then how do you implement mixin in C#? Is it possible at all?

  18. Made it all come together for me, thanks so much :)

Leave a comment