Returning Multiple Values Using Tuples in C# - dummies

Returning Multiple Values Using Tuples in C#

By John Paul Mueller, Bill Sempf, Chuck Sphar

In versions of C# prior to C# 7.0, every return value was a single object. It could be a really complex object, but it was still a single object. In C# 7.0, you can actually return multiple values using tuples. A tuple is a kind of dynamic array nominally containing two items that you can interpret as a key and value pair (but it isn’t strictly required). In C#, you can also create tuples containing more than two items. Many languages, such as Python, use tuples to simplify coding and to make interacting with values considerably easier.

C# 4.x actually introduced the concept of a Tuple as part of dynamic programming techniques. However, C# 7.0 advances the use of tuples to allow returning multiple values rather than just one object. This book doesn’t provide extensive coverage of tuples, but they work so well in returning complex data that you definitely need to know something about this use of tuples.

Using a single-entry tuple

A tuple relies on the Tuple data type, which can accept either one or two inputs, with two being the most common (otherwise, you can simply return a single object). The best way to work with tuples is to provide the data types of the variables you plan to provide as part of the declaration. Here’s an example of a method that returns a tuple:

static Tuple<string, int> getTuple()

{

// Return a single value using the tuple.

return new Tuple<string, int>("Hello", 123);

}

The code begins by specifying that getTuple() returns a Tuple consisting of two items, a string and an int. You use the new keyword to create an instance of Tuple, specify the data types in angle brackets, <string, int>, and then provide the data values. The getTuple() method effectively returns two values that you can manipulate individually, as shown here:

// This is where your program starts.

static void Main(string[] args)

{

// Obtain a single entry tuple.

Console.WriteLine(

getTuple().Item1 + " " + getTuple().Item2);

// Wait for user to acknowledge the results.

Console.WriteLine("Press Enter to terminate...");

Console.Read();

}

To access a single-entry tuple like this one, you call getTuple(), add a period, and then specify which item to use, Item1 or Item2. This example just demonstrates how tuples work, so it’s simple. The output looks like this:

Hello 123

Press Enter to terminate...

Using a tuple lets you return two values without resorting to complex data types or other odd structures. It makes your code simpler when the output requirements fit within the confines of a tuple. For example, when performing certain math operations, you need to return a result and a remainder or the real part and the imaginary part of a complex number.

Relying on the Create() method

An alternative way to create a tuple is to rely on the Create() method. The result is the same as when working with the method above. Here’s an example of using the Create() method:

// Use the Create() method.

var myTuple = Tuple.Create<string, int>("Hello", 123);

Console.WriteLine(myTuple.Item1 + "\t" + myTuple.Item2);

This approach isn’t quite as safe as using the method above because myTuple could end up with anything inside. You could further eliminate the <string, int> portion of the constructor to force the compiler to ascertain what myTuple should receive as input.

Using a multi-entry tuple

The true value of a tuple is in creating datasets using extremely easy coding methods. This is where you might choose to view Item1 as a key and Item2 as a value. Many dataset types today rely on the key and value paradigm and viewing a tuple in this way does make it incredibly useful. The following example shows the creation and return of a tuple dataset.

static Tuple<string, int>[] getTuple()

{

// Create a new tuple.

Tuple<string, int>[] aTuple =

{

new Tuple<string, int>("One", 1),

new Tuple<string, int>("Two", 2),

new Tuple<string, int>("Three", 3)

};

// Return a list of values using the tuple.

return aTuple;

}

You specify the return types of the Tuple data type. However, this example adds a pair of square brackets ([]) similar to those used for an array. The square brackets tell C# that this version of getTuple() returns multiple tuples, not just one.

To create a tuple dataset, you begin with the variable declaration as shown for aTuple. Each new entry into the tuple requires a new Tuple declaration with the requisite inputs as shown. The entire thing is placed within curly brackets and you end it with a semicolon. To return the tuple, you simply use the return statement as normal.

Accessing the tuple requires use of an enumerator, and you can do anything you would normally do with an enumerator, such as interact with the individual values using foreach. The following code shows how you might perform this task just for experimentation purposes:

static void Main(string[] args)

{

// Obtain a multiple entry tuple.

Tuple<string, int>[] myTuple = getTuple();

// Output the values.

foreach (var Item in myTuple)

{

Console.WriteLine(Item.Item1 + "\t" + Item.Item2);

}

// Wait for user to acknowledge the results.

Console.WriteLine("Press Enter to terminate...");

Console.Read();

}

The foreach statement places individual items from myTuple into Item. You then access the data elements individually by using Item1 and Item2 as before. Here’s the output from this example:

One 1

Two 2

Three 3

Press Enter to terminate...

Creating tuples with more than two items

Tuples can have one to eight items. If you want more than eight items, the eighth item must contain another tuple. Nesting tuples enables you to return an almost infinite number of items, but at some point you really do need to look at the complexity of your code and see whether you can keep the number of return items down. Otherwise, you find that your application executes slowly and uses a lot of resources. Here is an example that uses three items:

static Tuple<string, int, bool>[] getTuple()

{

// Create a new tuple.

Tuple<string, int, bool>[] aTuple =

{

new Tuple<string, int, bool>("One", 1, true),

new Tuple<string, int, bool>("Two", 2, false),

new Tuple<string, int, bool>("Three", 3, true)

};

// Return a list of values using the tuple.

return aTuple;

}

The technique follows the same pattern as before. The only difference is that you provide more values for each tuple. It also doesn’t matter whether you create a single tuple or a tuple array used as a dataset. Either choice allows you to use up to eight items per tuple.