Tuples and Anonymous Types in C#

This article explains tuples and anonymous types in C#.

Tuples and anonymous

Tuples

  1. Tuples are useful when we do not want to create a full-fledged class but rather special objects that will group other objects together.
  2. A tuple is a type of structural representation of data. It may be a record in a table.
  3. By default the .NET Framework supports tuples ranging from one element to 8 elements.
  4. It is also possible to create a tuple with n number of elements.

System.Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>

Where TRest is a generic.

For example: var numbers = new Tuple<Int32, Int32, Int32, Int32, Int32, Int32, Int32,Tuple<Int32>> (1, 2, 3, 4, 5, 6, 7, new Tuple<Int32>(19));

var num_1to3 = Tuple.Create(1, 2, 3);

Items in the preceding tuple are retrieved as num_1to3.Item1, num_1to3.Item2, num_1to3.Item3

var num_3to10 = new Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>>(4, 5, 6, 7, 8, 9, 10, num_1to3);

Items in the preceding tuple for the first 7 elements are retrieved as num_3to10.Item1, num_1to3.Item2, num_1to3.Item3 and so on.

Elements of num_1to3 that is nested with num_3to10 are retrieved as Rest.Item1, Rest.Item2 and Rest.Item3.

var num_11to16 = new Tuple< int, int, int, int, int, int,
Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>>>
(11, 12, 13, 14, 15, 16, num_3to10);


A third-level nested tuple is retrieved as Rest.Rest.Item1, Rest.Rest.Item2 and Rest.Rest.Item3.

From the preceding example we are combining multiple tuple to form a new tuple with n number of elements.

By this way we can eliminate the limitation of elements.

Tupel.Ceate is a static method. It supports only up to 8 elements. To initiate a tuple with more than 8 elements we are forced to use the constructor of the Tuple class.

It is very useful to multiple values as a single parameter.

The following are the methods supported by tuple:

Name Description of Tuples
Create<T1>(T1) Creates a new 1-tuple, or singleton.
Create(T1, T2) Creates a new 2-tuple, or pair.
Create(T1, T2, T3) Creates a new 3-tuple, or triple.
Create<T1, T2, T3, T4>(T1, T2, T3, T4) Creates a new 4-tuple, or quadruple.
Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) Creates a new 5-tuple, or quintuple.
Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) Creates a new 6-tuple, or sextuple.
Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) Creates a new 7-tuple, or septuple.
Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) Creates a new 8-tuple, or octuple.

Disadvantages

  • Elements of a tuple are sequentially named such as Item1, Item2 and so on. Custom naming of elements are not possible.
  • If the data is large its seems to be difficult to identify the elements.
  • Using anonymous types we can eliminate this problem.
  • But anonymous types need to be cast to the original type. Refer to the following example.

Example Program

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Collections;  
  6. namespace Tuples_and_anonymoustypes  
  7. {  
  8.     class Program   
  9.     {  
  10.         // Tuples and anonymous types are useful when we do not want to create full fledged class but rather than objects that will group other objects together  
  11.         // Tuples and anonymous types are nothing but objects that will help to group other objects  
  12.         // problem with tuples is naming conversion of objects ..... they are named sequentially as item1 , item2 etc  
  13.         // anonymous types helps us to create with proper naming conversions   
  14.         static void Main(string[] args)   
  15.         {  
  16.             string fulldetails = "harieswaran Sady 9600914291"/// i want to split these names so we try creating function  
  17.             var temp = split_tuples(fulldetails);  
  18.             Console.WriteLine("Using Tuples\n");  
  19.             Console.WriteLine("name ={0}\n", temp.Item1);  
  20.             Console.WriteLine("Nick name ={0}\n", temp.Item2);  
  21.             Console.WriteLine("mobile ={0}\n", temp.Item3);  
  22.             var ano_type = cast((split_ano_type(fulldetails)), new {  
  23.                 name = "", nickname = "", mobile = 10000000000000000  
  24.             });  
  25.             Console.WriteLine("Using Anonymous Types\n");  
  26.             Console.WriteLine("name ={0}\n", ano_type.name);  
  27.             Console.WriteLine("Nick name ={0}\n", ano_type.nickname); //////////// here naming converstion is done ie "nickname"  
  28.             Console.WriteLine("mobile ={0}\n", ano_type.mobile);  
  29.             Console.ReadKey();  
  30.         }  
  31.         private static object split_ano_type(string fulldetails) {  
  32.             string[] list = new string[2];  
  33.             list = fulldetails.Split(' ');  
  34.             return new {  
  35.                 name = list[0], nickname = list[1], mobile = Convert.ToInt64(list[2])  
  36.             };  
  37.         }  
  38.         private static Tuple < stringstring, Int64 > split_tuples(string fulldetails) {  
  39.             string[] list = new string[2];  
  40.             list = fulldetails.Split(' ');  
  41.             return Tuple.Create < stringstring, Int64 > (list[0], list[1], Convert.ToInt64(list[2]));  
  42.         }  
  43.         static T cast < T > (object fulldet, T Type)   
  44.         {  
  45.             return (T) fulldet;  
  46.         }  
  47.     }