Thursday, 28 January 2010

Tuple.Do

Another example of using extension methods to improve the readability of your code.


Version 4 of the .NET Framework introduces a new Tuple type; or rather, a set of Tuple types with different numbers of generic parameters. Tuples represent an ordered set of values, and are first-class features in some languages, particularly functional ones such as F#, which can return multiple values from a function, as in this example (which requires the PowerPack DLL):

let success, value = TryParseInt("42")

This is considerably more elegant than using an "out" parameter, which requires explicit variable declarations prior to the call.

In .NET 4.0, the BCL Tuple type is compatible with F#'s native Tuples, but can also be used from C# (and other CLI languages). C# lacks the syntactic sugar of F#, so the call above would return an instance of Tuple<bool, int> in which the "success" value was referred to by the Item1 property, and the value by the Item2 property.

For example:

var tuple = TryParseInt("42");
if (tuple.Item1)
{
  Console.WriteLine("Success: {0}", tuple.Item2);
}
else
{
  Console.WriteLine("Fail");
}


To me, this is less than ideal, and in thinking about it I was reminded of a common pattern from Ruby, where functions often take a "block" (Ruby's version of an Action or Func) and call it with the value(s) that would be returned from the method.

It's simple to reproduce this feature in C#, using an extension method on the Tuple<T1,T2> type:

using System;

namespace System.Linq
{
  public static class TupleDoExtensions
  {
    public static void Do<T1, T2>(this Tuple<T1, T2> tuple,
Action<T1, T2> action)
    {
      action(tuple.Item1, tuple.Item2);
    }
  }
}

With this extension method, we can specify meaningful names for the return values as the parameters to an anonymous method, thus:

TryParseInt("42").Do((success, value) =>
{
  if (success)
  {
    Console.WriteLine("Success: {0}", value);
  }
  else
  {
    Console.WriteLine("Fail");
  }
}

I think this code is a lot more readable. Another victory for extension methods.

1 comment:

Followers