Do you know what a Tuple is? Have you ever used a Tuple in C#? Have you heard of Tuples but assumed they were some complicated language feature? Tuples are very useful and very easy to use.

A Tuple is a very easy way to create objects that have multiple properties. Sure, creating classes is pretty easy too. But sometimes you just want to pass around a few pieces of information and not create a class just for that. And yes, I know you can use a struct instead. But both of those are very permanent. Do I really need to create a new Type in my project for something so simple? Here’s an example.

Today I was writing a method that returned some XML as string. The XML was going to be combined into a larger XML document. Sort of like this:

string xml = "<OuterNode><Section1>{0}</Section1></OuterNode>";
string inner = someService.GetXml();
string.Format(xml, inner);

Pretty simple right? But then I found out that I actually needed to get 2 portions of XML and they went into two different places:

string xml = “<OuterNode><Section1>{0}</Section1><Section2>{1}</Section2></OuterNoded>”; //simplified for the example

Sure there are lots of ways to do this:

  1. I could create a second method to return the second section of XML. Sure I could. But as much as I like single responsibility, the method I am using really is the right place to return both pieces of information. You’ll have to trust me on that :)
  2. I could create a class to hold both pieces of information like the one below. But, well, I am lazy. Plus, it just feels like a lot of overhead for this.
public class XmlHolder
{
    public string FirstPart {get; set;}
    public string SecondPart{ get;set;}
}

This is a use case where a Tuple can come in handy. A Tuple is a data structure that has a specific number of arguments, each of a specific Type and in a particular order. Please don’t be mislead by the word “structure”; a Tuple is a Class, not a Struct. Here is how you create a Tuple:

var firstTuple = Tuple.Create(xmlPartOne, xmlPartTwo); //Both of those arguments are strings.

Cool huh?

To get the data out:

var foo = firstTuple.Item1;
var bar = firstTuple.Item2;

OK, cool. But not super cool. “Item1”, “Item2”??? To me that seems sort of cheesy. But keep in mind, this is not a Dynamic Type object so you can’t name the properties. So I guess “Item1”, etc, will be ok.

Using the Create() method is cool. But what exactly does it create? Here is another way to write it that gives us some more insight:

Tuple<string, string> firstTuple = Tuple.Create(xmlPartOne, xmlPartTwo);

or

Tuple<string, string> firstTuple = new Tuple<string, string>(xmlPartOne, xmlPartTwo);

Now you can see what is really going on… Generics! I love Generics.

Do you have more than two items? That’s no problem:

var foo = Tuple.Create(string1, string2, string3, string4, string5); // assume these arguments are all strings please.

Got items of different types? Easy:

var foo = Tuple.Create(someString, someInt, someDecimal, somePersonObject, someThingElse);

That last one is the same as this:

Tuple<string, int, decimal, Person, SomeThingElse> firstTuple = Tuple.Create(someString, someInt, someDecimal, somePersonObject, someThingElse);

Easy right? And of course, thanks to Generics it is strongly typed.

These guys are really easy to use. Plus unlike an anonymous object, you can pass them around. Here I have a method that takes a Tuple as an argument.

public void DoSomething(Tuple<int, string, DateTime> input)
{
    int age = input.Item1;
    string name = input.Item2;
    DateTime hireDate = input.Item3;
}

The problem with the example above is that the developer who calls the method cant really tell what arguments the method really wants. It would probably be better to do this:

public void DoSomething(int age, string Name, DateTime hireDate)

So, Tuples are classes that should be used with some caution. Not because they are “bad” but they may not be the best kind of object to pass around because, while strongly typed, the properties aren’t “strongly named”. Certainly not a great choice for a public API. I think they should really be used sparingly. Certainly great for prototyping. And good for real applications too. But as a team lead, I wouldn’t want to see my team start using Tuples in place of regular classes all over the place!

Some more information:

Tuples were introduced in .Net 4.0.

Tuples are immutable. You can’t change the value once it is defined.

Items in the Tuple can be value or reference types.

Tuples are classes, not structs so they are on the heap, not the stack. That means they are garbage collected.

You can use Create() for Tuples with 1 item to 8:

  • Create(T1); // called a singleton
  • Create(T1, T2); // called a pair
  • Create(T1, T2, T3); //called a triple
  • Create(T1, T2, T3, T4); // called a quadruple
  • Create(T1, T2, T3, T4, T5); // called a quintuple
  • Create(T1, T2, T3, T4, T5, T6); // called a sextuple
  • Create(T1, T2, T3, T4, T5, T6, T7); // called a septuple
  • Create(T1, T2, T3, T4, T5, T6, T7, T8); // called an octuple
  • Plus you can pass another Tuple in as the 8th argument to make even larger Tuples!

Check them out, I hope you will enjoy using Tuples in your code.

4 thoughts on “Check out Tuples in C# – A handy, easy to use data structure

  1. Thanks for putting in the caution on Tuple over-use. You almost always want to avoid Tuples in public interfaces.

    Also, I’d mention that an anonymous object frequently works just as well and lets you actually name properties.

    Reply
  2. Pingback: Link Friday #5–Feb. 6, 2015 - Craig Wall

  3. Pingback: Dew Drop – February 6, 2015 (#1949) | Morning Dew

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>