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();
}

Advertisements