It’s Tuples All The Way Down!

By June 27, 2014C#

Tuples all the way downTuples in C# provide developers with a quick way of creating data structures without the need to define a separate class, but they should be used with caution.  I’ll demonstrate when you should–and shouldn’t–use tuples.  Spoiler alert: I do not recommend the code in the adjacent image!

First, let’s look at how you create a tuple.  Without tuples, if you needed a class with a few properties, you would create a separate POCO class, like this:

private class ValidationResult
    public bool HasError { get; set; }
    public int ErrorCode { get; set; }
    public string ErrorMessage { get; set; }

And to use this class, you would either pass values into a constructor, or use Object Initializer syntax:

var result = new ValidationResult
    HasError = true,
    ErrorCode = 205,
    ErrorMessage = "The address is invalid."

While there is absolutely nothing wrong with the code above, an alternative is to use a Tuple instead of defining a class for the sole purpose of returning data.  You can either use the Tuple constructor to specify the type of each element or use the Tuple.Create helper method to create the Tuple without specifying the types.

// use the constructor
var constructorTuple = new Tuple<bool, int, string>(true, 205, "The address is invalid.");
// use the Create helper
var createTuple = Tuple.Create(true, 205, "The address is invalid.");
// Assert that the types are equivalent
Debug.Assert(constructorTuple.Item1 == createTuple.Item1);
Debug.Assert(constructorTuple.Item2 == createTuple.Item2);
Debug.Assert(constructorTuple.Item3 == createTuple.Item3);

In the example above, the elements in each object are equivalent, but you’ll notice that the element names are simply “Item1, Item2, Item3” which is obviously not very descriptive.  Because of this, let’s talk about when you should and shouldn’t use Tuples.

When to use Tuples

As a general rule, you can use a Tuple when you need a privately-accessible object or instance variable where you can document what the Tuple contains, such as

  1. Short-lived access to an object when an anonymous type is not an option.
  2. Return multiple values from a private method instead of using several out parameters.
  3. Passing multiple parameters into a method that takes a single object parameter, such as Thread.Start() or ThreadPool.QueueUserWorkItem().

When NOT to use Tuples

Tuples are easy to use, but they should be used with caution.  A few scenarios to avoid:

  1. Because of the non-descriptive property names (Item1, Item2, Item3), only use Tuples within a method or between private methods. 
  2. Do not use Tuples for objects with more than a handful of elements.  The Create() helper method allows up 7 elements and you can nest tuples within tuples (as demonstrated in the image above), but this is never a good idea.  Create a POCO class if you need more than a few elements.
  3. Similar to #1, never expose a tuple through an API or when serializing an object to XML or JSON.  Exposing Item1 and Item2 as property names on the client systems will only cause confusion.

Have you seen other good (or bad) examples of Tuples?  Share them in the comments below!

If you are unfamiliar with the title of this blog, see: turtles all the way down.

The following two tabs change content below.