C# Tuple

Tuple: type name

A Tuple has many items. Each item can have any type. The Tuple class provides a unified syntax for creating objects with typed fields. Once created, the fields in the Tuple cannot be mutated. This makes the Tuple similar to a value type.

Class

3 items

Please note that the Tuple type is a class. It will be allocated in a separate location on the managed heap in memory. Once you create the Tuple, you cannot change the values of its fields. This makes the Tuple more like a struct.

StructSteps

Next:In this example, we create a three-item tuple using the special constructor syntax.

And:We then read the Item1, Item2 and Item3 properties. We do not modify them.

Program that uses 3 items in Tuple: C#

using System;

class Program
{
    static void Main()
    {
	// Create three-item tuple.
	Tuple<int, string, bool> tuple = new Tuple<int, string, bool>(1,
	    "cat", true);
	// Access tuple properties.
	if (tuple.Item1 == 1)
	{
	    Console.WriteLine(tuple.Item1);
	}
	if (tuple.Item2 == "dog")
	{
	    Console.WriteLine(tuple.Item2);
	}
	if (tuple.Item3)
	{
	    Console.WriteLine(tuple.Item3);
	}
    }
}

Output

1
True
Programming tip

Different types of items. When you create the Tuple, you can change the order and types of the fields in any way you want. If you would rather have a double, byte, char Tuple, change the declaration to Tuple<double, byte, char>.

Notice:You can have value types such as int and reference types such as string inside the Tuple.

4 items

Array type

Continuing on, the Tuple type can have more complex items inside it, such as arrays. You can also pass the Tuple type to other methods. In this example, we create a four-item Tuple with two arrays.

Array

Then:We initialize those arrays inside the constructor invocation. Next we pass the Tuple variable to another method.

Program that uses four-item Tuple: C#

using System;

class Program
{
    static void Main()
    {
	// Create four-item tuple; use var implicit type.
	var tuple = new Tuple<string, string[], int, int[]>("perl",
	    new string[] { "java", "c#" },
	    1,
	    new int[] { 2, 3 });
	// Pass tuple as argument.
	M(tuple);
    }

    static void M(Tuple<string, string[], int, int[]> tuple)
    {
	// Evaluate the tuple's items.
	Console.WriteLine(tuple.Item1);
	foreach (string value in tuple.Item2)
	{
	    Console.WriteLine(value);
	}
	Console.WriteLine(tuple.Item3);
	foreach (int value in tuple.Item4)
	{
	    Console.WriteLine(value);
	}
    }
}

Output

perl
java
c#
1
2
3
Var keyword

Var Tuple. Why does the example use the var keyword? The reason is pure syntactic sugar: it shortens the lines in the code example. If you were to type out the entire declaration twice, it wouldn't look as pretty.

Var Examples

Sextuple

A sextuple has six items. To create a sextuple, use the Tuple constructor. You have to specify each type of the sextuple's items in the type parameter list. In the sextuple constructor, you then specify the values that will be stored.

Program that uses sextuple: C#

using System;

class Program
{
    static void Main()
    {
	var sextuple = new Tuple<int, int, int, string, string, string>(1,
	    1, 2, "dot", "net", "perls");
	Console.WriteLine(sextuple);
    }
}

Output

(1, 1, 2, dot, net, perls)
Squares

In Visual Studio, you can hover over the var keyword. This will show you that the var "Represents a 6-tuple, or sextuple." Visual Studio will further describe the individual types of the arguments of the Tuple instance.

Visual Studio

Note:The naming of tuples is not important in many programs. But these terms can be useful when describing programs in a concise way.

The main difference between the Tuple type and a sextuple is that a Tuple can store nearly any number of items, while a sextuple must have six. Beyond septuples, we only have n-tuples.

A 2-tuple is called a pair.
A 3-tuple is called a triple.
A 4-tuple is called a quadruple.
A 5-tuple is called a quintuple.
A 6-tuple is called a sextuple.
A 7-tuple is called a septuple.
Larger tuples are called n-tuples.

Tuple.Create

Method call

Next, we invoke the Tuple.Create method.
We use it with three arguments:
a string literal,
an integer,
and a boolean value. The result of this method call is a tuple of type Tuple<string, int, bool>.

Also, we can use the implicit type var to simplify the syntax. The rest of the program simply tests the Item1, Item2, and Item3 property accessors. It prints the default string representation of the Tuple instance.

Program that uses Tuple.Create method: C#

using System;

class Program
{
    static void Main()
    {
	// Use Tuple.Create static method.
	var tuple = Tuple.Create("cat", 2, true);

	// Test value of string.
	string value = tuple.Item1;
	if (value == "cat")
	{
	    Console.WriteLine(true);
	}

	// Test Item2 and Item3.
	Console.WriteLine(tuple.Item2 == 10);
	Console.WriteLine(!tuple.Item3);

	// Write string representation.
	Console.WriteLine(tuple);
    }
}

Output

True
False
False
(cat, 2, True)
New keyword, constructor invocation

Internally, there is no elaborate algorithm involved in creating a tuple. The Tuple.Create method simply calls the constructor. And it returns the reference returned by the constructor.

Tip:There is essentially no functional reason to ever call Tuple.Create. It might have more pleasing syntax.

One implementation of Tuple.Create: .NET 4.0

public static Tuple<T1> Create<T1>(T1 item1)
{
    return new Tuple<T1>(item1);
}

Implementation

Framework: NET

This is the most important thing to know about the Tuple type. Tuple is a class, not a struct. It thus will be allocated upon the managed heap. Each class instance that is allocated adds to the burden of garbage collection.

Note:The properties Item1, Item2, and further do not have setters. You cannot assign them. The Tuple is immutable once created in memory.

Property

Read-only

Warning: exclamation mark

As noted, you must initialize all the values inside the Tuple instance to their final values when you call the Tuple constructor. You cannot change the value of a property like Item1 after the constructor has been called.

In this way, the Tuple acts like a struct in that its fields are immutable. This limitation can lead to more maintainable code that does not rely on field changes through time. It can also reduce performance.

Error:

Property or indexer 'System.Tuple...Item1' cannot be assigned to--it is read-only.

Performance

Performance optimization

Some performance tests were run on the Tuple and the KeyValuePair struct. This performance comparison is only relevant in cases where a Tuple of two items is used, as the KeyValuePair always has two items.

In the performance tests, KeyValuePair was faster when many instances were created, but Tuple was faster when the instance was passed to many methods as an argument. This is because the Tuple is a class and the KeyValuePair is a struct.

Tuple Versus KeyValuePair

Sort

Sorted letters: A to Z

How can you sort a collection of Tuple instances in an efficient and appropriate way?
With the Comparison delegate,
you can sort an array
or List of Tuple instances. It doesn't matter how many items the Tuple instances contain.

Sort Tuple List

Summary

The C# programming language

The Tuple is a typed,
immutable
and generic construct. It is a useful container for storing conceptually related data. A simple class with commented members and helper methods is more useful for important things.

Review:Tuple falls short in the field of information hiding. It excels as a useful short-term container.


C#: Collections