Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An introduction to Tuple

0.00/5 (No votes)
25 Oct 2010 2  
This article will explain about some of the benefits of using Tuple in C#4.0

Introduction

C#4.0 has introduce a new feature call Tuple.

Definition

In mathematics and computer science, a tuple is an ordered list of elements. In set theory, an (ordered) n-tuple is a sequence (or ordered list) of n elements, where n is a positive integer. There is also one 0-tuple, an empty sequence. (From Wikipedia)

Purpose:

Some time we need to return more than one value from a method or function.

Using the code

Let us perform a simple experiment for the basic arithmetic operations for the concept to understand

Let us first write our Calculate Function

/// Calculate 

private void Calculate(out int add, out int sub,out int mul,out int div)
{
   int num1 = 5;
   int num2 = 4;
   add = num1 + num2;
   sub = num1 - num2;
   mul = num1 * num2;
   div = num1 / num2;
}

Older approach (Till dotnet 3.5)

Approach 1: Using OUT parameter

The calling function is as under

1.jpg

The output is as expected

2.jpg

Approach 2: Using REF parameter

Similar to the first one but change OUT to REF

Approach 3: Using custom datatype

Create a CalculateEntity as depicted under

3.jpg

and modify our Calculate function as under

/// Calculate
private static CalculateEntity Calculate()
{
            CalculateEntity objCalculateEntity = new CalculateEntity();
            int num1 = 5;
            int num2 = 4;
            objCalculateEntity.Add = num1 + num2;
            objCalculateEntity.Sub = num1 - num2;
            objCalculateEntity.Mul = num1 * num2;
            objCalculateEntity.Div = num1 / num2;
            return objCalculateEntity;
}

The calling function will now be

4.jpg

 Approach 4:New Approach(Dotnet 4.0) - Using Tuple

5.jpg

As can be seen that using Tuple we can return multiple values from the function/method in a much more better and readable way.

The above example shows that tuple return s only the same type of datatypes.

Now lets see how we can return different datatypes from tuple

Let us modify the above Calculate function such that, the last argument will be double.

6.jpg

The result is as expected

7.jpg

Overloaded methods of Tuple

A Tuple has 8 overloaded methods whose signatures are given as under.

1-Tuple or Singleton

public static Tuple 
    Create
    (T1 item1);

2-Tuple or Pair

public static Tuple 
     Create
     (T1 item1, T2 item2);

3-Tuple or Triple

public static Tuple 
     Create
     (T1 item1, T2 item2, T3 item3);

4-Tuple or Quadruple

public static Tuple 
     Create
     (T1 item1, T2 item2, T3 item3, T4 item4);

5-Tuple or Quintuple

public static Tuple 
     Create
     (T1 item1, T2 item2, T3 item3, T4 item4,
     T5 item5);

6-Tuple or SexTuple

public static Tuple 
     Create
     (T1 item1, T2 item2, T3 item3, T4 item4, 
     T5 item5, T6 item6);

7-Tuple or SepTuple

public static Tuple
    Create
    (T1 item1, T2 item2, T3 item3, T4 item4, 
     T5 item5, T6 item6, T7 item7);

8-Tuple or Octuple

public static Tuple> 
      Create
      (T1 item1, T2 item2, T3 item3, T4 item4, 
       T5 item5, T6 item6, T7 item7, T8 item8);

A careful observation of the last overloaded method i.e. Octuple reveals that the last argument is again a tuple which indicates that it can carry further 8 items and the process goes on.

Let us see how can we use the last overloaded method.

Here I will build a simple Multiplication table that will use the last overloaded method.

The MultiplicationTable function is as under

8.jpg

We have highlighted the 8th parameter as how to use that.

The calling function is equally simple

int number = 5;
var tuple = MultiplicationTable(number);

    string format =
    "Multiplcation Table of {0} is" + Environment.NewLine +
    "------------------------------" + Environment.NewLine + Environment.NewLine +
    "{0} * 1     = {1} " + Environment.NewLine +
    "{0} * 2     = {2} " + Environment.NewLine +
    "{0} * 3     = {3} " + Environment.NewLine +
    "{0} * 4     = {4} " + Environment.NewLine +
    "{0} * 5     = {5} " + Environment.NewLine +
    "{0} * 6     = {6} " + Environment.NewLine +
    "{0} * 7     = {7} " + Environment.NewLine +
    "{0} * 8     = {8} " + Environment.NewLine +
    "{0} * 9     = {9} " + Environment.NewLine +
    "{0} * 10    = {10} " + Environment.NewLine;

    string result = string.Format(
    format
    , number
    , tuple.Item1
    , tuple.Item2
    , tuple.Item3
    , tuple.Item4
    , tuple.Item5
    , tuple.Item6
    , tuple.Item7
    , tuple.Rest.Item1
    , tuple.Rest.Item2
    , tuple.Rest.Item3

    );
Console.WriteLine(result);
Console.ReadKey(true);

The output is as under

9.jpg

As can be seen that it is very simple to use that.

But what if we need to determine at runtime the number of parameter on our tuple.

Its a bit tricky but by using reflection can be easily done. Let’s have a look

10.jpg

Though a complete details of reflection is not at all in the scope of this article but we will walk through as what the code is doing.

In the line

Type t = typeof(CSharpDemo.Program);

we are obtaining the type of the class which is Program here.

Then by the usage of the InvokeMember, we are invoking the method which is MultiplicationTable here . Since it accepts a parameter henceforth we are passing the same in the last argument.

11.jpg

The InvokeMember returns an object and after type casting that to string followed by string replacement we are splitting that by comma(,).

Then by applying the new Enumerable.Zip extension method whose generalized signature is Enumerable .Zip<TFirst,TSecond,TResult>, we are merging the two sequences in order to bring the needed display format and lastly by using the Foreach extension method we are displaying the needed result.

Create Custom Extension methods on Tuple

Tuples lacks the luster of ItemCount or ItemValues etc. But we can create so by using extension method on Tuple. Let us see how.

Create a class Call TupleExtension.cs and write the below code

using System;
using System.Linq;
using System.Reflection;

namespace CSharpDemo
{
    public static class TupleExtension
    {
        public static Tuple GetLengthAndMemeberValues(this Tuple targetTuple, string methodName, object[] param)
        {
            //Obtain the type of the class 
            Type t = typeof(CSharpDemo.Program);

            //Create an instance of the class
            object classInstance = Activator.CreateInstance(t);

            //Invoke the method
            object memberValues = t.InvokeMember(methodName, BindingFlags.InvokeMethod, null, classInstance, param);
            
            //Assign the needed value to the target tuple
            targetTuple = new Tuple
                 (ItemCount(memberValues), memberValues);

            return targetTuple;
        }

        /// 
        /// ItemCount
        /// Get the count of the number of items
        /// 
        /// 
        /// int

        public static int ItemCount(object o)
        {
            return o.ToString()
            .Replace("(", string.Empty)
            .Replace(")", string.Empty)
            .Split(',').Count();
        }
        
    }
}

To use the extension method we can go ahead as mentioned below

Tuple testTuple = new Tuple (0,null);

var resultantTuple = testTuple
                    .GetLengthAndMemeberValues("MultiplicationTable"
                    , new object[] { number });

Console.WriteLine("Number of TupleItems" + resultantTuple.Item1);
Console.WriteLine("Items of Tuple" + resultantTuple.Item2);

The output is as under

12.jpg

Conclusion:

In this short tutorial, we tried to explain most of the ways of using tuple, its usefulness and also an extension method of how to increase the tuple capability of overcoming its drawback which may come into use. This article also gives a small overview of the new Zip extension method and its usage. I have attached the sample code along with the article. Feel free to use and modify it as per your requirement.

Comments on the topic are highly appreciated for the improvement of the topic.

Thanks for reading the article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here