C# 7.0 – Tuples Re-Engineered

Tuples have been around for quite sometime as a convenient way of returning more than one value from a method. Even though Tuples were quite easy to use but from code-readability perspective, there were certainly room for improvement. In C# 7.0, team Microsoft made lot of enhancements with introduction of Tuple Types and Tuple Literals. Let’s review those changes. A typical use of Tuple could look as follows.

static void Main(string[] args)
 {
    Tuple<int, string> info = GetInfo();
    Console.WriteLine($"{info.Item1} -> {info.Item2}");
 }

static Tuple<int, string> GetInfo()
 {
    return new Tuple<int, string>(1, "Joe");
 }

With the new syntax, the GetInfo method can be rewritten as follows. This is basically Tuple Literals where the data items are comma separate within the parenthesis. Also notice that the function return type is using same syntax.

static (int, string) GetInfo()
{
    return (1, "Joe");
}

On the caller side, you can still use old way of calling the method.

static void Main(string[] args)
{
    (int, string) info = GetInfo();
    Console.WriteLine($"{info.Item1} -> {info.Item2}");
}

Of course, Type inference could still be applied as well when calling the method.

static void Main(string[] args)
{
    var info = GetInfo();
    Console.WriteLine($"{info.Item1} -> {info.Item2}");
}

As shown in image below, the tool-tip is showing appropriate type has been inferred.

1

However, the  declaration of Tuple without any variable names doesn’t make code easily readable and understandable. Good news is there is a better way. The code snippet below shows a newer version of GetInfo method. In this case, we have used the names of the variables which makes it much easier to understand as to what data is returned from this method.

static (int id, string name) GetInfo()
{
   return (id:1, name:"Joe");
}

These variables names can also be used in the Caller side as shown below.

static void Main(string[] args)
 {
   var info = GetInfo();
   Console.WriteLine($"{info.id} -> {info.name}");
 }

The type inference also shows these variable names as shown below.

2

When consuming the Tuples, there is even better way by what’s called “deconstructing” a tuple.  Code snipping below shows that the value returned by GetInfo method does not have a variable name but its consumed in the Console.WriteLine method just the tuple variable names.

static void Main(string[] args)
{
    (int id, string name) = GetInfo();
    Console.WriteLine($"{id} -> {name}");
}

For the var junkies out there, the code snippet above can be used as follows also.

static void Main(string[] args)
{
   (var id, var name) = GetInfo();
   Console.WriteLine($"{id} -> {name}");
}

And to simplify it even further, you can do as follows just with one var.

static void Main(string[] args)
{
   var ( id, name) = GetInfo();
   Console.WriteLine($"{id} -> {name}");
}

Until next, happy debugging!!

This entry was posted in .NET, CodeProject, Visual Studio 2017. Bookmark the permalink.

Leave a comment