A friend of mine recently tweeted a list of 10 "great" C# developer tips. I put purposely put the word great in quotes because, while there are some useful tips presented in this post, there is one that gets under my skin whenever anyone mentions it:
    The dreaded Tuple.
The Tuple was first introduced in .Net 4.0 and was meant to be a quick helper/replacement to creating very light-weight POCO classes (for those of you who hate acronyms, POCO stands for "Plain Old C# Object").
Say you have a method that needs to return an object with 2 string properties and 1 int property. You would create an object like this:
        public class Employee
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int YearsEmployed { get; set; }
Then your method signature would look like:
        public Employee GetEmployee(int employeeId) { ... }
As an answer to creating all of these little classes everywhere, the Tuple was created. Instead of creating tens to hundreds of POCO classes for your application, you could simply have a method signature like this:
        public Tuple<string, string, int> GetEmployee(int employeeId) { ... }
Awesome, right?!
Here are the top 3 reasons I HATE Tuples and you should too:

1. It promotes laziness.

The only reason you are using the Tuple is because you're lazy. You don't want to have to right click -> Add... -> Class... give it a name, type in your property names, reference it in your other projects, properly create an n-tier architecture, or, god forbid, think about IOC or DI (inversion of control and dependency injection for you initialism haters). Explicit coding be damned, you're better then having to do that. Laziness is good, if the output of it is faster or better... but in this case it's not either... leading me to:

2. It is a pain for consumers of your code.

Pop quiz: Given the following property in this class definition, tell me what the 3 items of the tuple represent.

public class Dog   
    public Tuple<string, string, string> Owner { get; set; }

I'll give you a minute... go ahead... ... got your answer?
If you said, "First Name", "Last Name", "Address" - you're wrong. I meant for it to be "Last Name", "First Name", "Eye Color". How could you have possibly known that? If you start using the Dog class with your assumption, but all the code I've written is on my intent, then we have a horrible data conflict. By saving yourself 30 seconds in not creating an explicit class, you have wasted at least 2 minutes of ever other developers' time. Which leads me to my last point...

3. You have to over document for it to be useful

Fine, you don't want to listen to me and you still want to use the Tuple. Hopefully you are documenting your code given your horrible choice so that when I, as a consumer of your code, come along and see Tuple<string, string>, I at least see some comments like:
///An owner where the Tuple has Item1: First Name and Item2: Last Name
However, I am a big fan of self-documenting code because it saves me time. There is no reason to add a comment like this:   
/// The first name
public string FirstName { get; set; }

But with your decision to use the Tuple, you now have to document EVERYTHING in order for it to make sense. Have you really saved yourself any time?   

Where are Tuples helpful?

Tuples are really helpful in prototype code. Sometimes you just need a quick way to represent related data in a code base you know you're not going to ship anywhere. Tuple it up wherever you want, just make sure that when it comes to actually writing the code, you get rid of them.
Tuples are also helpful in locally scoped code. If inside of a single method you want to use a Tuple to load up some data from a file before shoving it into a different return object, by all means. If I can see the local definition in my code window and its assignments, then I'm not lost. 
I'd love to hear what you think on the topic. Feel free to leave a comment here or on my twitter account.


Comment by David K.

This post (and the ensuing debate) was not my intention.

David K.
Comment by Aschwaubenon Cornbuckle III

Personally, I believe "David K" very much intended to start a debate, possibly even a ruckus.

Aschwaubenon Cornbuckle III
Comment by Ben.J.Bauer

@David K. You did poke the bear. :)