Using tuple in C#

By Mar 19, 2017

Description:

Here we show how to use tuples in Visual Studio 2017, and we give a few examples.

Preferencesoft

In this article, we will see how to use tuples, one of the new features of Visual Studio 2017. In previous versions of Visual Studio, tuples were already implemented in the form of a class. But in this version of VS, tuples are better integrated into C#. In fact, VS introduces a new class ValueTuple in addition to Tuple, but whose objects can be declared and used more easily.

Tuple

A tuple is a data structure that assembles data of different types in an orderly manner.

A tuple should not be confused with an array or a list which contains only elements of the same type. This data type could be compared with a struct type in which the fields are appointed item1, item2, ... But the tuples braces notation facilitates their declaration and usage.

It should be noted that this data type is already part of some formal languages like F#.

Installation in Visual Studio 2017

Create a new C# console application project (New Project > Console App), and call it ConsoleAppTry.

To take advantage of all the features of the tuples, we need to install a package from NuGet which is System.ValueTuple.

Using Tuples

Tuple Literal Values

A tuple can be created by surrounding objects with parenthesizes and separating the items with commas:

var t1 = ("Hello", 2017);
Console.WriteLine(t1);

Output:

(Hello, 2017)

Another way to declare a tuple is to use the constructor of class ValueTuple or use the create method:

var t2 = new ValueTuple<string, int, int>("Mar.", 18, 2017);
Console.WriteLine(t2);
var t3 = ValueTuple.Create("1", 18.002f, 256.89d);
Console.WriteLine(t3);

Output:

(Mar., 18, 2017)

(1, 18.002, 256.89)

Note that it is impossible to declare a singleton (1-Tuple) with parentheses, since parentheses are deleted during the evaluation.

In the following example:

var t1 = ("Start");

the t1 variable is of type string.

Get tuple items

A tuple has fields named Item1, Item2, Item3 and so on.

var tup = (0, "1", 0.2, 3f, 5d);
Console.WriteLine(tup.Item3);

Output:

    0.2

When you initialize a tuple, you can give names to each field, so you create a named tuple:

var person = (firstname : "John", lastname : "Doe", age : 40);
Console.WriteLine(string.Format("{0} {1}", person.firstname, person.lastname));

Output:

    John Doe

Affectation

We assign a tuple to another with the = symbol and this operation create a new tuple copying each element of the old one to the new. A tuple object, therefore, is not considered as a reference.

 var tup = (0, "1", 0.2, 3f, 5d);
 var dtup = tup;
 tup.Item1 = 1;
 Console.WriteLine(tup.Item1 + " <> " + dtup.Item1);

Output:

    1 <> 0

Deconstruction

Another way to access the elements of a tuple is to deconstruct it. Deconstruction of a tuple is an assignment of a tuple to another tuple consisting of variables, having to place each part of the first tuple in each of the corresponding variables.

 var tup = ("Happy", 417, 3f, 5d);
            string s;
            int i;
            float f;
            double d;
            (s, i, f, d) = tup;
            Console.WriteLine(string.Format("({0}, {1}, {2}, {3})", s, i, f, d));

Output:

    (Happy, 417, 3, 5)

It is also possible to make a declaring deconstruction that automatically declares the receiver tuple variables, in the current scope.

Example:

 var tup = ("OSS", 417, -0.123456789f, 3.141592653d);
            var (s, i, f, d) = tup;
            (string str, int n, float fl, double db) = tup;
            Console.WriteLine(string.Format("({0}, {1}, {2}, {3})", s, i, f, d));
            Console.WriteLine(string.Format("({0}, {1}, {2}, {3})", str, n, fl, db));

Output:

    (OSS, 417, -0,1234568, 3,141592653)
    (OSS, 417, -0,1234568, 3,141592653)

A spectacular use of the decomposition is the exchange of contents of two variables.

            int var1 = 85;
            int var2 = 178;
            Console.WriteLine(var1 + " , " + var2);
            (var1, var2) = (var2, var1);
            Console.WriteLine(var1 + " <-> " + var2);

Output:

    85 , 178

    178 <-> 85

But the exchange with the tuples is about 1.8 times slower than a classic exchange using an auxiliary variable.

Comparison

The operator == does not work with tuples. You must use the Equals method of the class ValueTuple.

       var tt = (0, "ABCDEF", 6656);
            if (tt.Equals((0, "ABCDEF", 6656)))
            {
                Console.WriteLine("Tuples are equal");
            }

Output:

    Tuples are equal

Function return

With tuples, we have another way to simultaneously return multiple variables by a function.

 class Program
    {
 
        static (string, int) Information() 
        {
            return ("John", 2017); // tuple literal
        }
 
        static (string name, int year) InformationN()
        {
            return ("John", 2017); 
        }
        static void Main(string[] args)
        {
            var inf = Information();
            Console.WriteLine(inf.Item1 + " , " + inf.Item2);
            var info = InformationN(); // impossible to reuse inf
            Console.WriteLine(info.name + " , " + info.year);
            Console.ReadLine();
        }
    }

Output:

    John , 2017
    John , 2017

In the declaration of the function informationN, we named the return tuple variables. This makes possible access to the fields with these names.

Examples

Example1

Let u and v two sequences defined by:

,  and ,    

These two sequences converge to the square root of x.

 class Program
    {
        static (double, double) Sqrt(int n, double v, double u) 
        {
            if (n == 0) return (v, u);
            var (vpred, upred) = Sqrt(n - 1, v, u);
            return (2 * vpred * upred / (vpred + upred), (vpred + upred) / 2);
        }
 
        static void Main(string[] args)
        {
            Console.WriteLine("Enter a number x>1:");
            var x = int.Parse(Console.ReadLine());
            Console.WriteLine(Sqrt(100, 1, x).Item1);
            Console.WriteLine(Math.Sqrt(x));
            Console.ReadLine();
        }
    }

Example2

Let's write a function that computes the min, max and average of an array of integers.

class Program
    {
        static (int, int, double) MinMaxAve(int[] score) 
        {
            int n = score.Length;
            int min; int max;
            double av;
            if (n == 0) return (0, 0, 0.0);
            av = min = max = score[0];
            for (int i=1; i < n; i++)
            {
                int element = score[i];
                if (element > max) max = element;
                if (element < min) min = element;
                av += element;
            }
            av /= n;
            return (min, max, av);
        }
 
        static void Main(string[] args)
        {
            int[] score = { 10, 15, 10 };
            Console.WriteLine(MinMaxAve(score));
            Console.ReadLine();
        }
    }

Output:

(10, 15, 11.6666666666667)


CSharp

Categories

Share

Follow


KodFor Privacy Policy