The .NET Framework version 4.0 introduced the ability to create tuples using several related, generic Tuple classes. Tuples provide a convenient way in which to link several values or objects, without first creating a class or structure to hold them.
What are Tuples?
The tuple is a mathematical structure that defines an ordered sequence of elements. In this context, ordered means that the order of items defines their relationship, rather than that the values are sorted. In mathematics, a tuple can have any number of related elements, including zero. Often the type of tuple will be described using the number of elements, such as 2-tuple, 5-tuple or 0-tuple for tuples containing two, five and zero values respectively. Usually a tuple instance will be written as a comma-separated list within parentheses. For example, a 3-tuple may be written as (1, 2, 3).
In addition to the notation, types of tuple also have names. The 0-tuple is often called the null tuple. A 1-tuple is a singleton, a 2-tuple a pair, and the structures containing between three and eight elements are triples, quadruples, quintuples, sextuples, septuples and octuples.
Tuples were introduced to the .NET framework with the release of version 4.0. They are used primarily in functional programming languages, such as F#. However, as a part of the framework they can be utilised by developers in other .NET languages, including C# and Visual Basic.
Support for tuples is provided by nine classes. Eight of these are generic classes that natively represent tuples with between one and eight elements; 0-tuples are not supported. The ninth class is a static class that allows simple tuple instantiation using generic methods. Although a maximum of eight items is supported in a single Tuple instance, larger lengths can be achieved by combining two or more tuples.
For object-oriented programming, tuples provide a quick way to link several values together. This can be useful when you wish to return multiple, related values from a method or property. You may also wish to pass several values to an object parameter, for example to have two values identifying a thread or provided in an event that follows an asynchronous operation.
There are limitations of tuples when compared with predefined structures and classes. Importantly, it should be noted that due to the targeting of the functional programming audience, tuples are immutable; once instantiated, the values within the set cannot be modified. Additionally, the values in a tuple are not enumerable. You should consider them similar to the properties of an anonymous type, rather than values in a collection.
Creating a Tuple
There are two ways in which a tuple can be instantiated using C#. The first is to use the constructor for one of the eight generic Tuple classes. The code below shows the creation of a 2-tuple containing two integer values.
var tuple = new Tuple<int, int>(1, 2);
Console.WriteLine(tuple); // Outputs "(1, 2)"
The types of the elements held in a tuple do not need to match. For example, the tuple created by the next sample contains a single character, a string and an integer value. In this case the values may represent a person's initial, surname and age in years.
var mixed = new Tuple<char, string, int>('B', "Smith", 25);
Console.WriteLine(mixed); // Outputs "(B, Smith, 25)"
Using the Tuple.Create Method
A second way to instantiate tuples is using a the static Create method of the Tuple class. This is the static class that exists only to generate new tuples. There are eight overloaded versions of the Create method, one for each variation of Tuple.
The following code recreates the previous 2-tuple using the method instead of a constructor:
var tuple = Tuple.Create<int, int>(1, 2);
When using the Create method, the data types can often be inferred from the arguments passed to the parameters. For example, in the code below we recreate the second example tuple but without providing type parameters.
var mixed = Tuple.Create('B', "Smith", 25);
Reading Tuple Values
The individual values in a tuple can be read using the properties of the appropriate Tuple<> class. Each class contains several numbered properties with the prefix, "Item". For example, the class that represents 3-tuples has three properties named "Item1", "Item2" and "Item3". The types of these properties are those of the generic class.
To show the use of the Item properties, let's first create a method that will return a tuple:
private static Tuple<int, int> Get2Tuple()
return Tuple.Create(1, 2);
We can now execute the method and obtain the two values independently using the code below. This shows an easy way to return multiple values from our method without resorting to using reference or output parameters.
var tuple = Get2Tuple();
Console.WriteLine(tuple.Item1); // Outputs "1"
Console.WriteLine(tuple.Item2); // Outputs "2"
NB: As the Tuple types are immutable, the Item properties are read-only.
2 November 2010