C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
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.
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.
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", "deves"); Console.WriteLine(sextuple); } } Output (1, 1, 2, dot, net, deves)
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 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.
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.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.
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.
Bytes: When a Tuple is passed as an argument, only 4 bytes need copying. But KeyValuePair, a struct, has more bytes.
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.
Here: We use the lambda syntax and pass in two arguments (a, b) and return the result of CompareTo on the Item2 string property.
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.
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.
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.