Last Saturday I went to the Developer Developer Developer conference in Cambridge (DDD East Anglia), which was both very good and free to attend.

As often happens at such conferences, it’s a throw-away remark or a discussion in the bar afterwards that has the most lasting impact rather than the subjects of the talks themselves.

In this case it was the talk by Alessandro Melchiori entitled Functional DDD that created the spark.

The traditional hand-coded approach

So, for example if you have some simple code like this, with an Item class that has a couple of properties, then its ToString isn’t very helpful:

using System;

namespace DDD1
{
    public class Item
    {
        public int Id { get; set; }
        public string Description { get; set; }
    }

    class Program
    {
        static void Main()
        {
            var item = new Item { Id = 123, Description = "My item" };
            Console.WriteLine(item);
        }
    }
}

The output you get is as follows:

DDD1.Item

So all you know is that you’re dealing with an Item, but you know nothing about its contents.

Traditionally you’d have to code up an override of ToString that knows about the properties of Item, something like this:

        public override string ToString()
        {
            return string.Format("Item {{ Id = {0}, Description = {1} }}", Id, Description);
        }
 

Which would give you this more useful output:

Item { Id = 123, Description = My item }

The JSON trick

In his talk, Alessandro Melchiori happened to mention using the Json.NET library’s JsonConvert class as an easy way of implementing ToString in your classes.

You can install Json.NET into your solution in a few seconds using NuGet. Then it’s just a case of adding a using statement and changing your ToString to use JsonConvert.SerializeObject:

using System;
using Newtonsoft.Json;

namespace DDD1
{
    public class Item
    {
        public int Id { get; set; }
        public string Description { get; set; }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }

    class Program
    {
        static void Main()
        {
            var item = new Item { Id = 123, Description = "My item" };
            Console.WriteLine(item);
        }
    }
}

This gives the following output:

{"Id":123,"Description":"My item"}

Now, that might not seem like a big deal.

The key point is that this one line of code inside the ToString will work however many properties we’ve got in our class, and will automatically be kept in sync as we add or remove properties. For most types it can provide really useful output for minimal coding effort.

Furthermore, if we stick that functionality in a base class then all you need to do to add this useful behaviour is derive from that class.

Adding a ValueBase class

If we’re creating a base class we can dispense with the Json.NET trick and use standard reflection to do clever things with our properties.

The following example makes it easy to create immutable types (notice that Item’s properties are read-only) by providing a generic constructor. It also includes a ToString and some sensible default implementations of Equals and GetHashCode too.

using System;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DDD1
{
    /// <summary>
    /// Base class for simple classes with properties
    /// </summary>
    public abstract class ValueBase
    {
        public override string ToString()
        {
            Type type = GetType();

            var result = new StringBuilder();
            result.AppendFormat("{0}:\n", type.Name);

            var props = type.GetProperties();
            foreach (var prop in props)
            {
                result.AppendFormat("    {0}: {1}\n", prop.Name, prop.GetValue(this));
            }

            return result.ToString();
        }

        public override bool Equals(object other)
        {
            Type type = GetType();

            if (other == null || !type.IsInstanceOfType(other))
            {
                return false;
            }

            foreach (var prop in type.GetProperties())
            {
                var thisProp = prop.GetValue(this);
                var thatProp = prop.GetValue(other);

                if (!thisProp.Equals(thatProp))
                {
                    return false;
                }
            }

            return true;
        }

        public override int GetHashCode()
        {
            Type type = GetType();
            var props = type.GetProperties();
            PropertyInfo firstProp = props.FirstOrDefault();
            return firstProp == null ? 0 : firstProp.GetValue(this).GetHashCode();
        }

        protected ValueBase(object properties)
        {
            Type type = GetType();
            var props = type.GetProperties();

            var otherProps = properties.GetType().GetProperties();

            foreach (PropertyInfo otherProp in otherProps)
            {
                props.Single(p => p.Name.Equals(otherProp.Name)).SetMethod.Invoke(this, new[] { otherProp.GetValue(properties) });
            }
        }
    }

    public class Item : ValueBase
    {
        public int Id { get; private set; }
        public string Description { get; private set; }

        public Item(object properties) : base(properties) { }
    }

    class Program
    {
        static void Main()
        {
            var item = new Item(new { Id = 123, Description = "My item" });
            Console.WriteLine(item);
        }
    }
}

Notice how simple the Item class is. Just by deriving it from the base class we’ve got a nice immutable package of properties with useful ToString output and sane equality comparisons (by property values rather than object references). If you had lots of small types like this then it would be easy to add this behaviour without having to write lots of boilerplate code each time.

If this all sounds familiar, it’s the kind of thing you typically get for free in functional languages such as Haskell and F#. Once you create an object it’s safely immutable and equality is automatically based on its content rather than its location in memory. That’s often useful behaviour in C# too, but there are normally lots of hoops to jump through to get there.

There are a couple of downsides to the ValueBase approach, however. First, we’re using reflection to save us coding effort, so the resulting code will be slower than the custom version you’d normally have. Second, we still have to derive from a base class and hit problems because C# doesn’t allow multiple inheritance. We can overcome both issues by switching to a solution using aspect-oriented programming (AOP) with PostSharp. I’ll cover that in the next article.