In this blog spot, I would like to show you some good use cases where we can use the new fancy tuple syntax in the new version of C#.
But first, let’s learn some history.
Microsoft introduces the first tuples in the C# version 4. Before the release of C# version 4, I have read a lot of blog posts about what the tuples are, using the tuples, and how they can be useful in some situation. These posts came from communities of various languages but not C#. So when I heard C# supported tuples too, I was eager to try it. But it was a disappointment.
This new “tuple feature” was only adding a new generic class
Tuple<T1>, Tuple<T1,T2> ….. Tuple<T1…T7, Tuple<T8>>
This class has properties named Item1 …. ItemX which hold a value of tuple. Ugh. In previous years, I tried to use these tuple classes more times, but every time the result was the same. The hard-to-read code which I have to rewrite to custom classes consisted of better-named properties than Item1 and Item2.
I have to admit I don’t know why someone would use this class Tuple<T1,T2> and what its purpose.
But with the new version of C# 7 tuples are something completely different. I have a love affair with F# language, so I am very happy to see the good tuple implementation finally comes to the C#.
So let’s quickly remind what the new tuples are.
If you want to return from function two values, you can now use this language constructs
On the first sight, this syntax may seem a little unusual, but I believe you will get used to. It is worth it.
The great thing is that compiler can wrap the tuple to the anonymous class.
This code is also perfectly valid
Maybe you notice the method Tuple returns the complex object that has two field(or properties) a,b and the only tuple syntax job is to do a “deconstructing” result into two variables.
So now what is it a good use case to use this fancy new feature?
Getting rid of “out parameters”.
The tuple is a great way how we can get rid of the methods with “out” parameters.
I think this is horrible piece of code. In my projects I usually have a helper class like this:
And then I can use this statement to parse value without out parameter:
var result = BoolParser.Try("true");
In new version of C#, you can use the tuple and rewrite this helper method like this:
It’s shorter a much more readable than the version with “out parameter”.
There are two common arguments against this approach.
- Using new feature “out var” is a better solution.
- The previous approach (returning BoolParserResult) is a better and more object oriented way how to deal with this problem.
They seem like valid points. I´ll tackle them one by one.
With new feature “Out var” you can call function TryParse like this:
That maybe looks good until you see this:
What value does variable i hold and why doesn’t the compiler protest the variable i does not exist in the current context?
This is called “variable scope leakage, “ and in my opinion, it wasn’t good design choice of the author of C#. I think it can cause worse readability and introduce some confusion. If you want to learn more, you can read this great post.
Return instance of class over tuple
One valid argument against using the tuple is we can return from method an instance of a simple class which just holds data. Like data transfer object(DTO). This approach we saw in the example with BoolParserResult. The class BoolParserResult contains the indicator of success and parsed data.
But now I believe using class for this parsing can be overengineering. By creating any class, we introduce to our program a new indirection or better said new abstraction.
We need to ask yourselves:
- It is an unavoidable abstraction or not?
- Does this new abstraction create for me some value, make the program more readable, usable(re-usable), testable?
- Do we reuse this class in the future?
The BoolParserResult is a class that probably be used only as return class from the method BoolParser and also this class probably isn’t change in future. It is a small stable class which won’t have any behavior just data. So why we need it. We need only values of this class. So create a class doesn’t provide any value to us and our program.
Another problem with DTO is that we need always create some name. And we all know naming is hard. It can stop your flow and drain your precious mental stamina. You can spend your time to inventing a name which doesn’t provide you any additional value. You can do much more interesting things than thinking about the name of the useless class.
Where not use a tuple.
I need tell a little about not so good use cases for tuples.
In my opinion the main problem with tuple is using it in public API which is consumed by other developers. When I am creating this kind of library, I tend to use small class and good named structure over tuples.
New tuple syntax is very nice and can be very useful. If you are not sure, just try it in private methods and after you see and learn the advantage and some caveats of tuples try to use it in more critical part of your application.