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 theTuple
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 theCreate()
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 viewItem1
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.