News
Microsoft's Adam Tuliper Explains Tuples in C# 7.0
In explaining new features in C# 7.0, Microsoft engineer Adam Tuliper found that few in the audience at a recent Visual Studio Live! conference were familiar with one of the new offerings, called tuples.
"Who's ever worked with the tuple support in System.Tuple?" Tuliper asked the audience at his "Exploring C# 7 New Features" presentation. "Okay so there's like three people that raised their hand on that, and tuples have been around for a long time. So that tells you, either you don't have a need for tuples, or the support that's been built in the language has not been that great for it. And I think it was a little bit kind of kludgy. You needed a specific use case for it."
Tuliper discussed some of those use cases that are addressed with a new feature in C# 7.0 that adds System.ValueTuple to the mix, joining System.Tuple that came with .NET 4.0 and C# 4.0.
Functionality around tuples is evolving along with C# and .NET, which are progressing together in this pattern:
Before going further into the new tuple functionality, though, what exactly is a tuple?
According to Microsoft documentation:
A tuple is a data structure that has a specific number and sequence of elements. An example of a tuple is a data structure with three elements (known as a 3-tuple or triple) that is used to store an identifier such as a person's name in the first element, a year in the second element, and the person's income for that year in the third element.
Or, as Thomas Levesque explained in his .NET blog, "A tuple is a finite ordered list of values, of possibly different types, which is used to bundle related values together without having to create a specific type to hold them."
Tuliper expanded on those definitions in his VS Live! presentation in Orlando. "The idea of a tuple is you can have two plus-values inside of an object that you just create on the fly. So think about the cases where you have a method and in that method you need to return more than one value and then you're like, 'well gosh do I need can I do different out parameters here? Should I create a class? Should I create a struct? Do I want to do it kind of like this C way where I'm gonna return a value for the method and pass something in my reference?' And so there's nothing that felt super clean on there. I don't really want to create a new class or struct just to return a value from this one method. So tuples can fill that role. You can just create them on the fly and return multiple values from something."
However, as noted, Tuliper acknowledged problems with previous System.Tuple approach. Levesque also detailed some of the drawbacks of the previous System.Tuple support:
They're classes, that is, reference types. This means they must be allocated on the heap, and garbage collected when they're no longer used. For applications where performance is critical, it can be an issue.
The fact that they can be null is often not desirable.
The elements in the tuple don't have names, or rather, they always have the same names (Item1, Item2 and so on), which are not meaningful at all. The Tuple<T1, T2> type conveys no information about what the tuple actually represents, which makes it a poor choice in public APIs."
Tuliper explained more about this.
"The difference is the built-in tuple support in System.Tuple relies on a reference type, and so when you use it, there's the allocations, there's an object behind the scenes," Tuliper said. "That same syntax is compatible with the new tuples. So the new tuples are in what's called System.ValueTuple, and the name might give it away. So behind the scenes it's changed structurally as to how its managed. It's no longer this reference-typed object. It is a value type behind the scenes -- in fact, more specifically a tuple is essentially a mutable struct."
Tuliper explained how tuples work in conjunction with one of his favorite features in the new-age C#: deconstruction, which is syntax for splitting up a tuple's parts and assigning them to new individual variables.
"What deconstruction means is you're taking some number of values in the right-hand side and assigning them to values on the left," Tuliper demonstrated in his hands-on coding example, noting that deconstruction works with other types beyond tuples.
"I'm not creating a single object," Tuliper demonstrated. "I'm taking tuples and what's called deconstructing them -- breaking them apart into individual values. So it's a nice way to just take multiple values and assign them to other variables."
Here's Tuliper's code demonstrating deconstruction:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace c_sharp_7.CSharp7
{
public class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Deconstruct(out int x, out int y)
{
x = X;
y = Y;
}
public void Deconstruct(out int x, out int y, out int q)
{
x = X;
y = Y;
q = 5;
}
}
}
Along with tuples, Tuliper delved deeply into other new features, such as pattern matching to do advanced comparisons with values in objects; and local functions for function-in-function support (which can be better than anonymous their use cases are understood completely). Other new features explained in the talk include "out" variables, throw expressions, generalized async return types and many more.
He supplied example coding projects to illustrate those and many other features coming in C# 7.1, 7.2, 7.3 and beyond.
All of that code, along with the slides Tuliper used in his presentation, can be found on the VS Live! site for Orlando, and you can grab it here.
The next Visual Studio Live! show will be in Las Vegas March 11-16.
About the Author
David Ramel is an editor and writer at Converge 360.