C# 11 Tuple Type

Before proceeding, now is an excellent time to introduce the Swift tuple. A tuple is, quite simply, a way to temporarily group multiple values into a single entity. The items stored in a tuple can be of any type, and there is no requirement that those values all be of the same type. A tuple could, for example, be constructed to contain an int value, a double value, and a string as follows:

(int, double, string) myTuple = (10, 432.43, "Refrigerator");

If you prefer not to declare the type of each tuple value, the var keyword may be used to tell the compiler to infer the value types:

var myTuple = (10, 432.43, "Refrigerator");

The elements of a tuple can be accessed using several different techniques. A specific tuple value may be accessed using dot notation to access Item<n> where <n> is the number of the item (with the first value being at position 1). The code below, for example, extracts item 2 from the tuple and assigns it to a new string variable:

var myTuple = (10, 432.43, "Refrigerator");
string item3 = myTuple.Item3;

System.Console.WriteLine(item3);

Tuple field names

When creating a tuple, you can also assign a name to each value. The names assigned to the values stored in a tuple can then be used when you reference those values in code, for example:

(int Count, double Price, string Description)  myTuple = (10, 432.43, "Refrigerator");

When using type inference to initialize a tuple, the field names are placed before each value:

var myTuple = (Count: 10, Price: 432.43, Description: "Refrigerator");

Once field names have been assigned, the corresponding values are accessed using dot notation, as demonstrated in the code sample below:

var myTuple = (Count: 10, Price: 432.43, Description: "Refrigerator");
(int Count, double Price, string Description)  myTuple2 = (10, 432.43, "Refrigerator");

Console.WriteLine ($"myTuple Price = {myTuple.Price}");
Console.WriteLine ($"myTuple2 Price = {myTuple2.Description}");

Returning tuples from methods

Tuples are particularly useful for returning multiple results from a method. For example, suppose we need to write a method that returns a tuple containing int, double, and string values. Each of these value types needs to be included in the method return type declaration as follows:

(int, double, string) GetProductData() {
.
.
}

When returning the type from within the method, we need to encapsulate the values in parentheses after the return statement:

(int, double, string) GetProductData() {
    return (10, 432.43, "Refrigerator");
}

When called, the result tuple can be assigned to a variable, and the individual values accessed using dot notation:

(int count, double price, string description) GetProductData()
{
    return (10, 432.43, "Refrigerator");
}

var myTuple = GetProductData();

int count = myTuple.Item1;
double price = myTuple.Item2;
string description = myTuple.Item3;

System.Console.WriteLine($"Count = {count}, Price = {price}, Description = {description}");

If you prefer to use field names instead of the Item<n> default names, all you need to do is include the field names and types when declaring the destination tuple:

(int count, double price, string description) GetProductData()
{
    return (10, 432.43, "Refrigerator");
}

(int count, double price, string description) myTuple = GetProductData();

int count = myTuple.count;
double price = myTuple.price;
string description = myTuple.description;

System.Console.WriteLine($"Count = {count}, Price = {price}, Description = {description}");

By far, the most convenient way to extract the values from a tuple, however, is to use type inference to assign the values to named variables as follows directly:

var (count, price, description) = GetProductData();

Using this approach, you can now access the variables directly without needing first to extract them from the tuple:

(int count, double price, string description) GetProductData()
{
    return (10, 432.43, "Refrigerator");
}

var (count, price, description) = GetProductData();

System.Console.WriteLine($"Count = {count}, Price = {price}, Description = {description}");

Tuples as method parameters

In addition to returning tuple results from methods, you can also pass tuples to methods. A method designed to accept our example tuple as an argument could be declared as follows:

public static void  DisplayProductData((int, double, string) productTuple) {

Alternatively, the tuple values may be assigned field names:

public static void  DisplayProductData((int count, double price, string description) productTuple) {

Once the method is declared, we can pass through a tuple in several ways. One option is to pass through the literal value to the method:

DisplayProductData((20, 29.99, "Water filter"));

Another option is, of course, to create a tuple object and pass it to the method:

var myTuple = (20, 29.99, "Water filter");
DisplayProductData(myTuple);

The following code shows an example of passing a tuple to a method:

void DisplayProductData((int count, double price, string description) productTuple)
{
    int count = productTuple.count;
    double price = productTuple.price;
    string description = productTuple.description;

    System.Console.WriteLine($"Count = {count}, Price = {price}, Description = {description}");
}

DisplayProductData((20, 29.99, "Water filter"));

Categories