Using Tuples in .NET

Introduction

 
We have all used classes and structs to define entities in our .NET applications. While great to use and forming the backbone of any .NET application, these are heavyweight objects which can define both data and actions. On some occasions, we need this entity only to be holding our data without any need for actions to be associated with it. That is when we can use the much less known object, Tuples. We will take a quick look at Tuples in this article and see how and where they can be used and look at the recent version of Tuples, the ValueTuple.

What are Tuples and how to use them

 
Tuples were introduced with .NET 4.0 and we can use them to store values in a unit like classes and structs. However, they are only to hold data and can be used where the use of classes or structs would be over complicated to just store data.
 
We will be creating a .NET Core 3.1 console application for demonstrating the use of Tuples. General statements will be run from the Main function and related functions will be in the Program class. Below is how Tuples are defined:
  1. //Declare an unnamed Tuple  
  2. var unnamedTuple = ("I am a string", 50);  
  3. Console.WriteLine($"The first value of the Tuple is {unnamedTuple.Item1}");  
  4. Console.WriteLine($"The second value of the Tuple is {unnamedTuple.Item2}");  
  5.   
  6. //Declare a named Tuple  
  7. var namedTuple = (stValue: "I am a string", numValue:50);  
  8. Console.WriteLine($"The first value of the Tuple is {namedTuple.stValue}");  
  9. Console.WriteLine($"The second value of the Tuple is {namedTuple.numValue}");  
In the above you see that we can define Tuples with members that are not named and access them using the Item1 and Item2 identifiers. However, a much better approach is to define them with a name and access them using these names as you see in the named tuple example. Please note that the option to use named tuples was not available before C# 7.0.

Below is another example of using Tuples with a more practical entity:
  1. //Decalre an Entity Tuple  
  2. var ID = 100;  
  3. var First_Name = "John";  
  4. var Last_Name = "Doe";  
  5. var Date_Birth = new DateTime(1980, 10, 1);  
  6. var Street_Address = "100 Street West";  
  7. var City = "Toronto";  
  8. var Province = "ON";  
  9. var Date_Joining = new DateTime(2020, 1, 15);  
  10.   
  11. var employee = (ID, First_Name, Last_Name, Date_Birth, Street_Address, City, Province, Date_Joining);  
  12.   
  13. // Displaying the values from the Tuple  
  14. Console.WriteLine($"ID: {employee.ID}");  
  15. Console.WriteLine($"First Name: {employee.First_Name}");  
  16. Console.WriteLine($"Last Name: {employee.Last_Name}");  
  17. Console.WriteLine($"Date of Birth: {employee.Date_Birth}");  
  18. Console.WriteLine($"Street Address: {employee.Street_Address}");  
  19. Console.WriteLine($"City: {employee.City}");  
  20. Console.WriteLine($"Province: {employee.Province}");  
  21. Console.WriteLine($"Date of Joining: {employee.Date_Joining}");  
In the above example, you see that the Tuple is used just as a class where we define members, assigns values to them, and places them in one unit which can be sent to functions and received from them, as shown below:
  1. //Sending a Tuple as a parameter to a function  
  2. SendTuple(employee);  
  3. private static void SendTuple((int ID, string First_Name, string Last_Name, DateTime Date_Birth, string Street_Address, string City, string Province, DateTime Date_Joining) employee)  
  4. {  
  5.     Console.WriteLine($"Display from within the Send Tuple function");  
  6.     Console.WriteLine($"ID: {employee.ID}");  
  7.     Console.WriteLine($"First Name: {employee.First_Name}");  
  8.     Console.WriteLine($"Last Name: {employee.Last_Name}");  
  9.     Console.WriteLine($"Date of Birth: {employee.Date_Birth}");  
  10.     Console.WriteLine($"Street Address: {employee.Street_Address}");  
  11.     Console.WriteLine($"City: {employee.City}");  
  12.     Console.WriteLine($"Province: {employee.Province}");  
  13.     Console.WriteLine($"Date of Joining: {employee.Date_Joining}");  
  14. }  
  15.   //Receiving a Tuple as a return value from a function  
  16.            (int ID, string First_Name, string Last_Name, DateTime Date_Birth, string Street_Address, string City, string Province, DateTime Date_Joining) emp = ReceiveTuple();  
  17.   
  18. // Displaying the values from the returned Tuple  
  19. Console.WriteLine($"Display from values returned from the Tuple function");  
  20. Console.WriteLine($"ID: {emp.ID}");  
  21. Console.WriteLine($"First Name: {emp.First_Name}");  
  22. Console.WriteLine($"Last Name: {emp.Last_Name}");  
  23. Console.WriteLine($"Date of Birth: {emp.Date_Birth}");  
  24. Console.WriteLine($"Street Address: {emp.Street_Address}");  
  25. Console.WriteLine($"City: {emp.City}");  
  26. Console.WriteLine($"Province: {emp.Province}");  
  27. Console.WriteLine($"Date of Joining: {emp.Date_Joining}");  
  28.   
  29. private static (int ID, string First_Name, string Last_Name, DateTime Date_Birth, string Street_Address, string City, string Province, DateTime Date_Joining) ReceiveTuple()  
  30. {  
  31.     var ID = 200;  
  32.     var First_Name = "Jane";  
  33.     var Last_Name = "Doe";  
  34.     var Date_Birth = new DateTime(1990, 05, 30);  
  35.     var Street_Address = "275 Street East";  
  36.     var City = "Toronto";  
  37.     var Province = "ON";  
  38.     var Date_Joining = new DateTime(2020, 2, 20);  
  39.     var employee = (ID, First_Name, Last_Name, Date_Birth, Street_Address, City, Province, Date_Joining);  
  40.     return employee;  
As you can see here, Tuples are a simple way to combine and store related data where we do not need behavior elements as in classes.
 

The ValueTuple introduced in C# 7.0

 
The use of Tuples comes with an issue. They are reference types and the excess usage of them will result in performance issues. Hence, a new type, ValueTuple was introduced that we can find in .NET framework 4.7 and higher, as well as .NET standard 2.0 and higher. If the ValueTuple is not available in your project, you can add it by installing the System.ValueTuple NuGet package.
 
Another advantage of ValueTuples is that you are not restricted to the limit of eight members as in the case of a regular Tuple. All examples used in this article are ValueTuples, as these provide the new features described here.
 
Value tuples can also be explicitly defined as below or by using the general syntax, as used in the above examples:
  1. Console.WriteLine($"Display Value Tuples");  
  2. ValueTuple<intstringstring> emplo = (1, "John""Doe");  
  3. Console.WriteLine($"The first value of the Tuple is {emplo.Item1}");  
  4. Console.WriteLine($"The second value of the Tuple is {emplo.Item2}");  
  5. Console.WriteLine($"The third value of the Tuple is {emplo.Item3}");  

Summary

 
In this article, we have looked at Tuples to store related data in a unit, to pass data as a unit to a function or return multiple values from a function. However, these Tuples had many issues which include unnamed members, reference type existence, maximum of eight members etc. All these issues have been removed with the new ValueTuple introduced in C# 7.0 and the syntax to use these is also simple. Therefore, my recommendation would be to use ValueTuples whenever we need to store or group related data without the need to store behavior.