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
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
The output is as expected
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
and modify our Calculate function as under
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
Approach 4:New Approach(Dotnet 4.0) - Using Tuple
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.
The result is as expected
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
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
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
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.
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)
{
Type t = typeof(CSharpDemo.Program);
object classInstance = Activator.CreateInstance(t);
object memberValues = t.InvokeMember(methodName, BindingFlags.InvokeMethod, null, classInstance, param);
targetTuple = new Tuple
(ItemCount(memberValues), memberValues);
return targetTuple;
}
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
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.