Tuples in .NET world and C# 7.0 improvements

RubiksCode
87 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Back in the day when I was a young developer, I was using output parameters. Then I figured out it is somewhat complicated to test functions with output parameters, and that their use is clunky at best. Also, out parameters don’t work with async function, because of CLR limitations. In general, I liked them less and less. So, I started writing DTOs – Data Transfer Objects, to avoid this kind of situation and keep my design as clean as possible. Then I started writing a lot of DTOs, and I mean a lot of DTOs. In fact, they were affecting cleanness of my code now. Especially when I had to group values which are really not having much in common. This was happening usually on DAL modules. All of this seemed like a lot of overhead just to pass some values around. And then, I have discovered Tuples.

Definitions

Tuples come from set theory, where the tuple is defined as a finite ordered list of elements. Unlike ordered lists, the same element can appear more than once inside the tuple. They can pretty much look like this – (a, b, a). Still, the order is important. Some other definitions say that tuples are ordered multiset. To sum it up in few points:

Tuple is used to describe some form of the finite sequence of elements ..*Element can appear more than once in the tuple ..*The order of the elements in the tuple is important In computer science, the form of the tuples and the way that are used variates from one programming language to another. Tuple in Pyton is an immutable list, in Scala it is used to mix different types, and in functional languages tuples are used for pattern matching. It is debatable, but JavaScript object can be considered a tuple.

Tuples in .Net

In the .NET world Tuple is a data structure with a specific number and sequence of elements, first introduced in .NET 4.0. It is important to notice that Tuple is a structure, ie. value type and that it’s fields are public and mutable. Here is an example:

Tuples example 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
·using System;
namespace TuplesCharp7
{
public class TupleExample1
{
public static Tuple<string, string, int> GetNameBlogAndAge()
{
return new Tuple<string, string, int>(
"Nikola Zivkovic", "www.rubikscode.net", 30);
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

As mentioned before, Tuples can be used to return multiple values from the function, without using out or ref parameters, but that is not their only use. They can be used to pass multiple values trough the one function parameter. Also, since they have value equality, Tuples can be used if you need a dictionary with multiple keys or list with multiple values on each position. Still, before C# 7.0, using Tuples was not so natural for many software craftsmen. They seem a bit stodgy and you always had to remember which value has been assigned to which item of the tuple. A code was cleaner, in a sense that there were no more DTOs as before, but tuples definitely added a lot of mess. Also, they were not applicable to the public API, for the same reasons.

Tuple Types and Tuple Literals in C# 7.0

In order to make Tuples more friendly, guys at Microsoft introduced some new features in C# 7.0. These allow us to define function return values in more understandable manner. For example, our function from before can now be presented like this:

Tuples example 2
1
2
3
4
5
6
7
8
9
10
11
·namespace TuplesCharp7
{
public class TupleExample2
{
public static (string, string, int) GetNameBlogAndAge()
{
return ("Nikola Zivkovic", "www.rubikscode.net", 30);
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

We can see it is a little bit easier to understand what is going on now, but still, if you want to access those values, we are still gonna use confusing “Item1”, "Item2", etc. names. This bump is also upgrated in new version of C#. Now, we can name each field in the Tuple like this:

Tuples example 3
1
2
3
4
5
6
7
8
9
10
11
·namespace TuplesCharp7
{
public class TupleExample3
{
public static (string name, string blog, int age) GetNameBlogAndAge()
{
return ("Nikola Zivkovic", "www.rubikscode.net", 30);
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Or asigning element names inside litelar itself, like this:

Tuples example 4
1
2
3
4
5
6
7
8
9
10
11
12
·using System;
namespace TuplesCharp7
{
class TupleExample4
{
public static (string name, string blog, int age) GetNameBlogAndAge()
{
return (name: "Nikola Zivkovic", blog: "www.rubikscode.net", age: 30);
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Consuming Tuple can be done in more natural way. Here are examples of all use cases:

Tuples usage examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
·using System;
namespace TuplesCharp7
{
class UsageExamples
{
static void Examples()
{
// Example 1
var personExample1 = TupleExample1.GetNameBlogAndAge();
Console.WriteLine("{0} has a blog called {1}, and he is {2} years old",
personExample1.Item1, personExample1.Item2, personExample1.Item3);
// Example 2
var (name, blog, age) = TupleExample2.GetNameBlogAndAge();
Console.WriteLine("{0} has a blog called {1}, and he is {2} years old",
name, blog, age);
// Example 3
var personExample3 = TupleExample3.GetNameBlogAndAge();
Console.WriteLine("{0} has a blog called {1}, and he is {2} years old",
personExample3.name, personExample3.blog, personExample3.age);
// Example 4
var personExample4 = TupleExample4.GetNameBlogAndAge();
Console.WriteLine("{0} has a blog called {1}, and he is {2} years old",
personExample4.name, personExample4.blog, personExample4.age);
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The other thing that is also very usefull is that tuples now can be used in deconstructing declaration as it is shownin example 2. This means that you can split tuple into its elements and assign those elements separately to new variables.

Conclusion

Tuples solve a lot of problems that you had with DTOs and output parameters. Also, problems with its usability and naming are upgraded in C# 7.0. Frankly, it reminds me of JSON objects, and also some of the Typescript features. Remember how Typescript was presented as JavaScript for C# developers? It seems to me that now this change is pushing C# towards something that will remind us of JavaScript. Who knows, maybe these two currents will find middle ground in one unified solution.

Read more posts from the author at Rubik's Code.

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content