JavaScript is good, so as part of JavaScript the Good Parts, prototypal inheritance must be really, really good.
Some time ago while I was working on a supply chain management system for a large UK based department store I came across some interesting C# code, here’s an example:
public class Customer : Address
{
}
Unfortunately Clarence above has no address, but thanks to Homeless Hotspots he is a Mac address. A stark warning of the implications of favouring inheritance over composition.
When asked the C# programmer said that they preferred inheritance as it was quicker to implement in C# than composition. For a single object it is easier to favour inheritance over composition in C#, even more so with C# 2.0 before the advent of auto-implemented properties. Here’s the somewhat more verbose Customer has an Address:
public class Customer
{
private readonly Address _address = new Address();
public Address Address
{
get
{
return _address;
}
}
}
The Gang of Four in their seminal Design Patterns book postulated in the first chapter that good object-orientated design should favour composition over inheritance. Unfortunately most people seem to skip the first chapter and dive head first into specific patterns like singleton, proxy and factory. Spring’s AbstractSingletonProxyFactoryBean shows the way:
Arbitrary misuse of inheritance is not confined to enterprise developers, we only need to look at the Button class in WPF to see a long hierarchy and over 160 members.
Thankfully the Intellisense in Visual Studio 2012 has an intelligent search to help you find the needle in the haystack. In the future it may be possible to apply machine learning approaches for prediction so that we can scale from hundreds to thousands of members.
Prototypal Inheritance
Programmers often find JavaScript inheritance hard to understand. This is probably a good thing, creating a pit of success where composition is by default favoured over inheritance.
To this end I have implemented Prototypal Inheritance for C#. The source is available on BitBucket and I will publish a Nuget package for enterprise developers in the near future.
Prototype-based programming is actually quite a natural fit for C# particularly with the dynamic support introduced in C# 4, combined with the var keyword introduced in C# 3, it’s often hard to distinguish C# from JavaScript.
Now for the science: in prototypal inheritance every object is a clone of another object.
Pseudoclassical
Let’s start with the pseudoclassical JavaScript example from Douglas Crockford’s book:
var Mammal = function (name) { this.name = name; };
Mammal.prototype.get_name = function () { return this.name; };
Mammal.prototype.says = function () { return this.saying || ''; };
var myMammal = new Mammal('Herb the Mammal');
var name = myMammal.get_name(); // 'Herb the Mammal'
var Cat = function (name) {
this.name = name;
this.saying = 'meow';
};
Cat.prototype = new Mammal();
Cat.prototype.get_name = function () {
return this.says() + ' ' + this.name + ' ' + this.says();
};
var myCat = new Cat('Henrietta');
var says = myCat.says(); // 'meow'
var name = myCat.get_name();
You can’t beat a good taxonomy of the animal kingdom to show the awesome power of OO. Now you can create almost exactly the same code in C# using the Prototype library:
var Mammal = Prototype.Constructor<string>((that, name_) => that.Name = name_);
Mammal.Prototype.GetName = (System.Func<dynamic, string>)(that => that.Name);
Mammal.Prototype.Says = (System.Action<dynamic>)(that =>
{
string saying = that.Saying;
Echo(saying);
});
var myMammal = Mammal.New("Herb the Mammal");
string herb = myMammal.GetName();
Echo(herb);
var Cat = Prototype.Constructor<string>((that, name_) =>
{
that.Name = name_;
that.Saying = "meow";
});
Cat.Prototype = Mammal.New();
var myCat = Cat.New("Henrietta");
string name = myCat.GetName();
Echo(name);
Prototypal
Again starting with a JavaScript prototypal example:
var myMammal = {
name: 'Herb the Mammal',
get_name: function () {
return this.name;
},
says: function () {
return this.saying || '';
}
};
Now in C# taking advantage of anonymous objects:
var Class = Prototype.FromObject(new
{
Name = "Hello",
GetName = (System.Func<dynamic, string>)(that => that.Name)
});
dynamic myMammal = Class.New();
There it is, prototypal inheritance for C#, you’re welcome!