C#

.NET Array Dictionary List String 2D Async DataTable Dates DateTime Enum File For Foreach Format IEnumerable If IndexOf Lambda Parse Path Process Property Regex Replace Row Sort Split Static StringBuilder Substring Switch Tuple Window

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.