Caffeine-Powered Life

Pluralization in C#

My response to Phil Haack’s post on singular and plural phrasing.


public static class Pluralization

{

    private static readonly ConcurrentDictionary dictionary;

    private static Func<string, string> defaultPluralizationRule = (s) => s.EndsWith("s") ? "es" : "s";



    static Pluralization()

    {

        dictionary = new ConcurrentDictionary();            

    }



    public static void Add(string singular, string plural)

    {

        if (singular.IsBlank())

            throw new ArgumentException("singular string is not allowed to be null or empty");



        if (plural.IsBlank())

            throw new ArgumentException("plural string is not allowed to be null or empty");



        dictionary[singular] = plural;

    }



    public static void Add(IEnumerable<KeyValuePair<string, string>> keyValuePairs)

    {

        keyValuePairs.ForEach(kvp => Add(kvp.Key, kvp.Value));

    }



    public static void Clear()

    {

        dictionary.Clear();

    }



    public static void SetDefaultPluralizationRule(Func<string, string> rule)

    {

        defaultPluralizationRule = rule;

    }



    public static string Pluralize(this int count, string singular, string plural = null)

    {

        if (count < 0)

            throw new ArgumentOutOfRangeException("count", "count may not be less than 0");

        

        if (plural.IsBlank() == false)

            Add(singular, plural);



        if (count == 1)

            return OutputString(count, singular);



        if (dictionary.TryGetValue(singular, out plural))

            return OutputString(count, plural);



        return OutputString(count, singular + defaultPluralizationRule(singular));

    }



    private static string OutputString(int i, string s)

    {

        return string.Format("{0} {1}", i, s);

    }

}  

A gist is available here, with unit tests. Benefits of my approach…

  • Pluralized forms are cached, so this can be something that is built during application startup.
  • The default action is a function. If the word ends in an “s”, “es” is added to the end. Otherwise, just an “s” is added to the end of the word. This policy works for a lot of words in the English language.

What do you think?

Comments