C#

Tuple. 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. A program can assume a tuple will never change, so it can be reused. Tuple is a useful generic class.
3 items. Please note that the Tuple type is a class. Once we create the Tuple, we cannot change the values of its fields. This makes the Tuple more like a string.

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.

Based on: .NET 4.5

C# program that uses 3 items in Tuple

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
Item types. When we create a Tuple, we specify the order and types of the fields. If you would rather have a double, byte, char Tuple, change the declaration to Tuple<double, byte, char>.

Note:We can have value types (such as int) and reference types (such as string) inside a Tuple.


4 items. Continuing on, a Tuple can have more complex items inside it, such as arrays. We can also pass the Tuple to other methods.

Here:In this example, we create a four-item Tuple with two arrays—string and int arrays.

Arrays

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

Var:Why does the example use the var keyword? The reason is pure syntactic sugar. Var shortens the lines in the code example.

Var
C# program that uses four-item Tuple

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
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.
C# program that uses sextuple

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)
In Visual Studio, we can hover the mouse over the var keyword. This shows that the var "Represents a 6-tuple, or sextuple." Visual Studio further describes the tuple's individual types.

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

Names:Beyond septuples, we only have n-tuples. These terms will make you sound really smart.

A tuple is an ordered list of elements. In mathematics, an n-tuple is a sequence (or ordered list) of "n" elements, where "n" is a non-negative integer.

Tuple: Wikipedia
Names:

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. Next we invoke this method. We use Create() with three arguments: a string literal, an integer and a boolean value.

Result:The Create() method returns a class of type Tuple<string, int, bool>. It has three items.

Program:The code does a series of tests of the Tuple. It tests Item1, Item2 and Item3.

C# program that uses Tuple.Create method

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)
Internals. There is no elaborate algorithm devoted to tuple creation. The Tuple.Create method calls a constructor and returns a reference.

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);
}
Class implementation. Tuple is not a struct. It is a class. It 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. We cannot assign them. A Tuple is immutable once created in memory.

ClassProperty: Get, Set
Read-only. We must initialize all values inside a Tuple to their final values when we call the constructor. We cannot change a property (like Item1) after the constructor has run.

Tip: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. I ran a benchmark on Tuple and the KeyValuePair struct. This comparison is relevant only in cases where a Tuple of two items is used.

Result:KeyValuePair is faster when many instances are created. But Tuple is faster when the reference is passed to methods.

Tuple vs. KeyValuePair

Bytes:When a Tuple is passed as an argument, only 4 bytes need copying. But KeyValuePair, a struct, has more bytes.

Struct
Sort. Tuples can be sorted. A Tuple is a great way to encapsulate units of data. But it can make sorting harder. A Comparison delegate is needed.

First:This program creates a List and adds three new Tuple instances to it. We invoke the Sort method on the List.

Sort List

Here:We use the lambda syntax and pass in two arguments (a, b) and return the result of CompareTo on the Item2 string property.

Lambdas

Tip:To sort on the int, change the lambda to return a.Item1.CompareTo(b.Item1). A reverse sort would be b.Item2.CompareTo(a.Item2).

Tip 2:There are other ways we can sort Tuples. For example, we can use the query syntax from LINQ.

LINQ
C# program that sorts List of Tuple instances

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<Tuple<int, string>> list = new List<Tuple<int, string>>();
	list.Add(new Tuple<int, string>(1, "cat"));
	list.Add(new Tuple<int, string>(100, "apple"));
	list.Add(new Tuple<int, string>(2, "zebra"));

	// Use Sort method with Comparison delegate.
	// ... Has two parameters; return comparison of Item2 on each.
	list.Sort((a, b) => a.Item2.CompareTo(b.Item2));

	foreach (var element in list)
	{
	    Console.WriteLine(element);
	}
    }
}

Output

(100, apple)
(1, cat)
(2, zebra)
Return multiple values. This is an age-old problem. A method may need to return many things, not just one. A tuple can return multiple values (with less code than a class would require).

Note:This causes an allocation. Using ref and out parameters would be faster for a method that is hot.

Parameters Ref, Out

Note 2:A Tuple has advantages. It is a reference and can be reused. Less copying is needed when passed to other methods.

C# program that returns multiple values

using System;

class Program
{
    static Tuple<string, int> NameAndId()
    {
	// This method returns multiple values.
	return new Tuple<string, int>("Gudrun", 673);
    }

    static void Main(string[] args)
    {
	var result = NameAndId();
	string name = result.Item1;
	int id = result.Item2;
	// Display the multiple values returned.
	Console.WriteLine(name);
	Console.WriteLine(id);
    }
}

Output

Gudrun
673
A summary. The Tuple is a typed, immutable, generic construct. That sounds impressive. Tuple is a useful container for storing conceptually related data.
Limits. A simple class with commented members and helper methods is more useful for important things. But Tuple shines as a short-term container.