Pluralization (Pluralisation!) in C#

http://www.davidwhitney.co.uk/Blog/?p=242

So today at work we were spitting some league table-ish (shh! unreleased feature!) data onto a screen and I realised I was going to have to manually pluralise “0 donations”, “1 donation”, “2 donations” depending on the number of donations having been made. I felt a little bit of the crazy eye coming on, because I’ve solved this problem a hundred times before.

By “solved” I mean, “I’ve written a shitty if(..) statement to solve this problem a hundred times before”, which totally sucks.  And I exclaimed “but surely this is a problem everybody that has ever displayed text has faced, it can’t possibly be that we all solve this every day”.

Turns out, that this has pretty much been the case until recently. Rails has Pluralize methods, and most ORMs clearly have this functionality to some extent but I’d never happened across a general purpose .NET library to do the job.  After sitting and expressing my utter disbelieve that this isn’t (at least in it’s simplest form) a solved problem, I actually used some GoogleFu to discover that it was.

So, in .NET4, it looks like Microsoft actually got round to implementing this in the framework, I’d not happened across it before, but it’s pretty freaking cool.

So let me introduce, if I may, the System.Data.Entity.Design.PluralizationServices namespace!

The more observant of you might notice that it appears to be in a namespace with “Entity” in the title. I suspect it was cooked up as part of EF (boo! hiss!) but luckily, you don’t need to actually reference the main System.Data.Entity assembly as it’s been separated out into a satellite assembly.  It also looks like localization is hiding behind one giant NotImplementedException(); currently, but the usage is pretty simple and calmed me down in no time.

var _pluralizationService = PluralizationService.CreateService(Thread.CurrentThread.CurrentCulture);
var plural = _pluralizationService.Pluralize(singular);

and that’s it!

Almost too good to be true, but it actually works, managing “donation”=>”donations”, “sheep”=>”sheep” and as esoterically pointed out on twitter, even “cardex”=>”cardecies”. Which is really pretty cool.

We took it a little further and added support to it in our suite of extension methods for the ASP.NET MVC HtmlHelper class, so in our MVC views we can do this:

<%@ Import Namespace="Extensions" %>
<%=Html.Language().CorrectTenseForQuantity(Model.Quantity, "word") %>

Which I thought was pretty tasty (and at the very least, gives us the same thing the Rails guys have, just with slightly more explicit syntax (my personal preference).

I’ve put our extension implementation up as a Gist on GitHub here if anyone wants to see the full implementation.

Pretty cool.