Tuples are Evil and Should be Treated as Such

While working on a particular area of the a clients code (C#) I came across method with a signature similar to the following:

public Tuple<bool, decimal, decimal, decimal, int, int> CheckState(int aParameter)

At first glace you may think that there is nothing wrong with this but think about it – what does that bool actually represent? What about the second of the decimal values? Well, the developer had obviously thought about this and had added a comment above the signature – but it only specified 5 values, not the 6 that are in the Tuples definition (that’s because code comments lie).

But the problems with Tuples don’t stop with not being able to see what the method is returning – oh no. What happens when you are on the other side of the method – calling it and consuming the response?

var stateResult = CheckState(1);

bool isValid = stateResult.Item1;
decimal highValue = stateResult.Item2;
decimal lowValue = stateResult.Item3;
decimal alarmValue = stateResult.Item4;
int inPort = stateResult.Item5;
int outPort = stateResult.Item6;

What is not obvious from this is that when you are using Visual Studio the Intellisence is not going to help you out here – Item1, what is that again? Ok, you may be able to see it’s a bool but how much does that help you? What about the decimal values? Which is which?

Obviously the developer who put this together needed to return a handful of values but why oh why did he use a Tuple instead of creating a simple POCO/DTO?

public class StateResult
{
    public bool IsValid {get; set;}
    public decimal HighValue {get; set;}
    public decimal LowValue {get; set;}
    public decimal AlarmValue {get; set;}
    public int InPort {get; set;}
    public int OutPort {get; set;}
}

The method signature now becomes:

public StateResult CheckState(int aParameter)

While the usage would now be:

var stateResult = CheckState(1);
bool isValue = stateResult.IsValid;
decimal highValue = stateResult.HighValue;
decimal lowValue = stateResult.LowValue;
decimal alarmValue = stateResult.AlarmValue;
int inPort = stateResult.InPort;
int outPort = stateResult.OutPort;

For the sake a less than a dozen lines of code it has become more readable, almost self-describing, easier to use and to maintain.

So the next time you think about using a Tuple – remember, the next developer may know where you live and may own an axe 😉

 

One comment

  1. Love it Dave. I have just had this conversation last week with anyone who cared to listen(which was nobody!). Why oh why couldn’t Microsoft have implemented Tuples properly. The good news though is that it looks like for .NET 6 they will be doing so so we can all sleep a little easier.

Comments are closed.