Tuples in C#

Tuples in C# 7 with Examples

In this article, I am going to discuss the Tuples in C# with examples. Please read our previous article where we discussed the Digit Separators in C# with some examples. Tuples are not completely new in C# 7. In .NET Framework 4.0, a set of Tuple classes has been introduced in the System.Tuple namespace. As part of this article, we will discuss the following pointers.

  1. Why we need Tuples?
  2. What are the different ways to return more than one value from a method?
  3. Examples of Tuples Before C# 7.
  4. Understanding the Problems with the Tuples Before C# 7.
  5. How to use Tuples from C# 7.
  6. Tuples in C# with named Parameters
  7. Guidelines to use Tuples
Why we need Tuples?

If you want to return more than one value from a method then you need to use Tuples. And in the programming world, it is a very common thing to return multiple values from a method. Tuples in C# 7, provides a better mechanism to return multiple values from a method.

What are the different ways to return more than one value from a method?

Following are the different mechanisms available in C# to return multiple values from a method:

Using Custom DataType: You can return multiple values from a method by using a custom data type (i.e. class) as the return type of the method. But sometimes we don’t need or don’t want to use classes and objects because that’s just too much for the given purpose.

Using Ref and Out variable: You can also return more than one value from the method either by using the “out” or “ref” parameters. Using “out” or “ref” parameters quite difficult to understand and moreover, the “out” and “ref” parameters will not work with the async methods.

Using dynamic keyword: You can also return multiple values from a method by using the dynamic keyword as the return type. The dynamic keyword was introduced in C# 4. But from a performance point of view, we probably don’t want to use dynamic. 

As I already told tuples are not new to C# 7. They come with improvements in C# 7. So, let us first understand the Tuples which are there before C# 7.

Tuples Before C# 7:

In the following example, we are returning two values (integer and double) from the Calculate method using Tuple class. In the following example, within the calculate method we create an instance of the Tuple class by calling the static Create method of the Tuple class. To the static Create method, we are passing the required integer and double values that we want to return from the method. In the Main method, we are storing the result in a Tuple variable and then accessing the first value i.e. count using the item1 property and the second value using the item2 property.

using System;
using System.Collections.Generic;
namespace TulesDemo
{
    class Program
    {
        static void Main()
        {
            var values = new List<double>() { 10, 20, 30, 40, 50 };
            Tuple<int, double> t = Calulate(values);
            Console.WriteLine($"There are {t.Item1} values and their sum is {t.Item2}");
            Console.ReadKey();
        }

        //Declaring the return type as Tuple<int, double>
        private static Tuple<int, double> Calulate(IEnumerable<double> values)
        {
            int count = 0;
            double sum = 0.0;
            foreach (var value in values)
            {
                count++;
                sum += value;
            }

            //Creating an object of Tuple class by calling the static Create method
            Tuple<int, double> t = Tuple.Create(count, sum);

            //Returning the tuple instance
            return t;
        }
    }
}
Problems with the above code:

There are 3 major problems in the above code with Tuple:

The first problem is that the Tuples in C# are classes, i.e. reference types. As reference types, the memory is allocated on the heap area and garbage collected only when they are no longer used. For applications where performance is the major concerns, it can be an issue.

The second problem is that the elements in the tuple don’t have any names and you can only access them by using the names Item1, Item2, Item3, etc. which are not meaningful at all. The Tuple<T1, T2> type does not provide any information about what the tuple actually represents which makes it a poor choice in public APIs.

The third problem is that you can use a maximum of 8 properties in a Tuple in C#. If you want to return more than 8 values from a method,  then again the last argument of the Tuple must be another Tuple. This makes the syntax more difficult to understand.

How to overcome the above Problems?

To overcome the above three problems, C# 7 comes with a new feature which is used to improve the support for tuples in C#. With C# 7, now it is possible to declare the tuple as “inline”, which is like an anonymous type, except that they are not limited to the current method. 

Let’s modify the code as shown below to see the use of new improvements of Tuples in C# 7.
using System;
using System.Collections.Generic;
namespace TulesDemo
{
    class Program
    {
        static void Main()
        {
            var values = new List<double>() { 10, 20, 30, 40, 50 };
            var result = Calulate(values);
            Console.WriteLine($"There are {result.Item1} values and their sum is {result.Item2}");
            Console.ReadKey();
        }
        
        private static (int, double) Calulate(IEnumerable<double> values)
        {
            int count = 0;
            double sum = 0.0;
            foreach (var value in values)
            {
                count++;
                sum += value;
            }
            return (count, sum);
        }
    }
}

As you can see in the above code, we are returning two values i.e. int and double from the Calculate method and then we are accessing the values. This is much better. If you want then you can also give specific names to the tuples returning values.

Tuples in C# with named Parameters:

With  C# 7, now it is possible to provide the tuples parameters with user-defined names. To understand this let’s modify the code as shown below. Here we are providing names for the tuple parameters in the Calculate method as count and sum. Now, in the method you can access, these parameters and moreover you will also get intelligence.

using System;
using System.Collections.Generic;
namespace TulesDemo
{
    class Program
    {
        static void Main()
        {
            var values = new List<double>() { 10, 20, 30, 40, 50 };
            var result = Calulate(values);
            Console.WriteLine($"There are {result.count} values and their sum is {result.sum}");
            Console.ReadKey();
        }
        
        private static (int count, double sum) Calulate(IEnumerable<double> values)
        {
            int count = 0;
            double sum = 0.0;
            foreach (var value in values)
            {
                count++;
                sum += value;
            }
            return (count, sum);
        }
    }
}
Provide Explicitly names while storing the Result:

In the following example, we are providing explicitly names to the tuple properties with the Main method where we calling the Calculate method. In this case, you don’t require to provide the variable name as we can access the properties directly with the provided name.

using System;
using System.Collections.Generic;
namespace TulesDemo
{
    class Program
    {
        static void Main()
        {
            var values = new List<double>() { 10, 20, 30, 40, 50 };
            var(countResult, SumResult) = Calulate(values);
            Console.WriteLine($"There are {countResult} values and their sum is {SumResult}");
            Console.ReadKey();
        }
        
        private static (int count, double sum) Calulate(IEnumerable<double> values)
        {
            int count = 0;
            double sum = 0.0;
            foreach (var value in values)
            {
                count++;
                sum += value;
            }
            return (count, sum);
        }
    }
}
Guidelines to use Tuples:

Basically, one and the most important question that comes to our mind is when to use Tuples and when to use Classes to return more than one values from a method in C#.

The answer is it depends on the business requirement. However, there are some guidelines and rules that you need to follow which will guide you to choose between them:

Tuples in C# 7 are values, so they are copied by value, rather than by reference.

Most of the time, this should not be an issue. However, if you are passing around tuples of large structs, this might have an impact on the performance of the application. Ref locals/returns can be used to work around these performance issues that we will discuss in our upcoming articles. As the tuples in C# 7 are values, so modifying a copy will not change the original copy. 

Just use common sense

For any situation where you might consider using a tuple: simply ask yourself the question: “will a tuple simplify the code here“. If the answer is “yes“, then use a tuple. And that ultimately is the primary consideration over whether to use a tuple or a custom class.

So in the simple word we can say that Tuple is an ordered sequence of heterogeneous objects. The Tuples in C# are going to be used when a method is going to return more than one values.

Tuples in C# 7 with Examples

In the next article, I am going to discuss Deconstruction in C# some examples. Here, in this article, I try to explain the Tuples in C# 7 step by step with some simple examples. 

Leave a Reply

Your email address will not be published. Required fields are marked *