General

C# Tuple with Examples

Tuples can be used to store a finite sequence of homogeneous or heterogeneous data of fixed sizes and can be used to return multiple values from a method

Like anonymous types, tuples provide a simple way to store a set of values. The main purpose of tuples is to safely return multiple values from a method without resorting to out parameters (something you cannot do with anonymous types).

C# 7’s tuple functionality relies on a set of supporting generic structs named System.ValueTuple<…>. These are not part of .NET Framework 4.6, and are contained in an assembly called System.ValueTuple, available in a NuGet package of the same name. You must add the NuGet package System.ValueTuple in order to use it on platforms that do not include the types.

The following example creates a tuple with three elements:

Tuples are value types, with mutable (read/write) elements:

However, when you initialize a tuple, you can use new language features that give better names to each field.Doing so creates a named tuple. Named tuples still have elements named Item1Item2Item3 and so on. But they also have synonyms for any of those elements that you have named. You create a named tuple by specifying the names for each element. One way is to specify the names as part of the tuple initialization:

Unlike with anonymous types, you can specify a tuple type explicitly. Just list each
of the element types in parentheses:

This means that you can usefully return a tuple from a lambda method:

Alternative writing syntax. When we create a Tuple, we can specify the order and types of the fields. If you would rather have a double, byte, char Tuple, change the declaration to Tuple. Tuples play well with generics, so the following types are all legal:

 

Returning Multiple Values

Methods return a single object. Tuples enable you to package multiple values in that single object more easily.

 

Naming Tuple Elements

You can optionally give meaningful names to elements when creating tuple literals:

You can do the same when specifying tuple types:

Note that you can still treat the elements as unnamed and refer to them as Item1, Item2, etc. (although Visual Studio hides these fields from IntelliSense).

Tuples are type-compatible with one another if their element types match up (in order). Their element names need not:

Our particular example leads to confusing results:

Type erasure

We stated previously that the C# compiler handles anonymous types by building custom classes with named properties for each of the elements. With tuples, C# works differently and leverages a pre-existing family of generic structs:

Each of the ValueType<> structs has fields named Item1, Item2, and so on.

Hence, (string,int) is an alias for ValueTuple<string,int>, and this means that named tuple elements have no corresponding property names in the underlying types. Instead, the names exist only in the source code, and in the imagination of the compiler. At runtime, the names mostly disappear, so if you decompile a program that refers to named tuple elements, you’ll see just references to Item1, Item2, etc. Further, when you examine a tuple variable in a debugger after having assigned it to an object.

ValueTuple.Create

You can also create tuples via a factory method on the (nongeneric) ValueTuple type:

Named elements cannot be created in this way, as element naming relies on compiler magic

Deconstructing Tuples

Tuples implicitly support the deconstruction pattern.  So you can easily deconstruct a tuple into individual variables. So,
instead of doing this:

The syntax for deconstruction is confusingly similar to the syntax for declaring a tuple with named elements! The following highlights the difference:

Here’s another example, this time when calling a method, and with type inference (var):

 

 

 

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.