It's no secret that C# 7 is one of the biggest updates to Microsoft's homegrown programming language that the .NET community has ever seen. So far, previews of the 7th iteration of updates to the C# language specification and its associated APIs have let us play with exciting new features like  local functions and the inline declaration of out variables. These new features, while extremely useful, are relatively self-explanatory since they simply build or improve upon old features of the language. Among these improvements, however, is a new feature that isn't so obvious: the tuple value type.

If you've worked with languages like Python before (or if you've worked extensively with relational data in C#), you may already be familiar with the concept of tuples. (Since tuples have always been available via an API in C# before the new version, you might have seen them before!) Even though C# 7 doesn't modify the definition of a tuple, it (fortunately) makes implementing them much easier and much more useful.

Since not everyone is familiar with what a tuple actually is, this post is first going to briefly walk through the background of tuples. (I promise this won't be a history lesson, but you will be able to get an idea of how tuples might be useful in the scope of your application.) Then, I'll go through a quick example to show you how you can get the new tuple features offered by C# 7 up and running in your project right now as well as the best way to incorporate them into a new or existing app.

Getting to Know Tuples

In brief, a tuple is an ordered, immutable list of heterogeneous (yet strongly typed) data values. Now, that sentence is short, but man, is it dense. Instead of trying to explain that piece-by-piece, I think it'd be much easier to just take a look at an example of a tuple in C# 7:


var authorCharacteristics = ("Christian", "Gaetano", 22, true, "GrapeCity");

And that's it! That's all it takes to declare a tuple in C# 7 - one delightfully simple assignment statement. Specifically, this new syntax is referred to as a tuple literal. But before we get to that, let's analyze this line of code to see if we can wrap our heads around what a tuple actually is.

As I mentioned above, a tuple is essentially a list of data values. What makes a tuple different from, say, a C# List object or an Array, however, is that it provides the ability to store a variable amount of different data types and attach semantic names to each value (more on that a little later). That's still a little hard to understand without examples, so let's look at some more. These are all examples of valid tuples:


var tup1 = ("Hello", "world", "!", true); // 3 strings, 1 bool

var tup2 = ("What is the meaning of life?", 42); // 1 string, 1 int

var tup3 = ("I don't get it.", "Why not?", "I'm not sure!"); // 3 strings

The examples above illustrate what tuples are: objects that support the storage of different data types (although it's not required!) and different amounts of data. While the tuple literal syntax makes declaring these objects much easier, creating these objects was always possible using the .NET Framework's System.Tuple API. So what's the big deal? Read on to find out how the addition of tuples to value types in C# 7 makes them more powerful than ever!

What's new in C# 7?

The power of a value type

The most important additional features of tuples in C# 7 are derived from them being instated as a value type. This has two very important implications:

  1. Performance. Now, you don't need to store a tuple as an instantiated class to use it in your code. For example, if you want to return a tuple from a function, you can just return one via a tuple literal. Then, it's up to caller to either use the tuple immediately or store it. This gives you more control over memory consumption and garbage collection (GC) in your application. Basically, tuple value types eliminate the memory overhead of the old tuple API.
  2. Software design. Just like with the int or string value types, you can now indicate that your function will return a tuple value. Why is this any different than using the old System.Tuple API? Semantics. You can now easily specify the types and names of data values that your function will return in a tuple. Take a look at the examples below to see this in action.

Semantic naming of tuple items

As stated above, this is one of the most powerful features of the new tuple features in C# 7: you can specify custom names for items in a declared tuple. Before we show how this new feature works, let's take a look at the built-in semantics of the System.Tuple API:


// Create a 7-tuple with some different population values
var population = new System.Tuple<string, int, int, int, int, int, int>(
"New York", 7891957, 7781984,
7894862, 7071639, 7322564, 8008278);

// Hmmm...how do we access the 2nd population value?

// Perhaps we could do something like population.secondPop?

// Nope! This tuple only has built-in naming of items:

console.WriteLine(population.Item3); // 7781984

Okay, so that's not such a big deal. We declared our own tuple, so we know where the item we want is located. But what if that tuple were returned from a function in one of our references?


// Retrieve 7-tuple from library function

var population = DataLib.GetPop();

// Okay, first, we should see what city this population is for...

var city = population.??? // Wait, how do we know which item has the city name?! Uh oh...

Clearly, things become much more complicated as we begin working with tuples returned from functions we didn't write ourselves. Along with the memory allocation concerns, this is the major problem that has kept the C# community from adopting tuples on a larger scale. But now, with the dawn of C#7, that's all changed! Behold, custom semantic naming of tuple items!


/* In DataLib: */

(string city, int firstPop, int secondPop, int thirdPop, int fourthPop, int fifthPop, int sixthPop) GetPop() {

// retrieve some population data here

return (cityName, pop1, pop2, pop3, pop4, pop5, pop6);

}

/* In our application: */

var population = DataLib.GetPop();

// Hey, there's a new property! It's called city! Woo!

var city = population.city;
var pop3 = population.thirdPop;

// We stored the city name and third population value, but now the 'population' object (tuple) will be garbage collected

And there you have it, the new power of tuple value types in C# 7! The above code snippet clearly illustrates the performance and usability benefits of including tuples in the exclusive "C# value type club."

Using Tuple Value Types Right Now

Are you totally convinced that tuple value types are the future of C#? Ready to get going and rewrite all of your functions to use them? Not so fast! First, you'll have to take a few quick steps to enable the new syntax and features in your IDE. Check out the easy steps below:

  1. You'll have to be using the latest update of Visual Studio 2015 or the Visual Studio 2017 RC to take advantage of the tuple value type, so make sure you're on the cutting edge before moving on!
  2. Open up your C# project in Visual Studio.
  3. Right click on your project in the Solution Explorer and click "Manage NuGet Packages..."
    Right click on your project and then click "Manage NuGet Packages..." to find the Tuple value type extensions.

    Right click on your project and then click "Manage NuGet Packages..." to find the Tuple value type extensions.

  4. Click 'Browse' in the upper left hand corner of the NuGet Package Explorer then search for 'ValueTuple.' Click the Install button and click through any prompts.
    Search for ValueTuple and install the System.ValueTuple package to your project to activate the new features.

    Search for ValueTuple and install the System.ValueTuple package to your project to activate the new features.

  5. Begin using tuple value types in your project!

That wasn't so bad, was it? Eventually, the tuple value type will be included in the C# language by default, and you won't need to take the above steps to use it. For now, though, at least the NuGet install procedure is pretty straightforward!

Where You Should Use Tuples

Before I sign off, I just want to say a few words about where in an application tuples can even be useful. Now that you have access to the API in the .NET Framework and the new tuple value type, there are all kinds of ways you can incorporate them into your code. I'll just quickly list some of the most common and useful places for tuples:

  1. Data access: tuples are commonly used to store data records (rows) loaded from a database. This is a particularly useful case because tuples can store a row of data no matter how many fields it has or what data types those fields store. This use case works with both the System.Tuple API and the value type, although the value type allows some more functionality with semantic naming.
  2. Returning multiple values from a function: as seen in our examples above, this is really the most useful case for the new tuple literal syntax and tuple value types. The new features of tuples allow you to return immutable lists of strongly typed values from your functions. Most importantly, you can provide semantic naming for each of these returned values, making your API easier to use and your code more readable.
  3. Storing/passing data in code: in addition to passing tuples around as return types from functions, you can also use them to store data in global variables that can be used throughout your code. Rather than declaring multiple constant strings, consider storing them as named items in a tuple instead:
    
    var Constants = (MY_NAME: "Christian Gaetano", MY_AGE: 22, MY_PASSION: "pizza");
    

And With That...

Go forth and use tuples! The tuple value type isn't the most innovative feature to be added to the C# language, but it is certainly one of the most useful. Not only can the new tuple value type increase your applications performance, it can also bring your code to a new level of simplicity and readability.

If you want to learn more about the new tuple value type, check out the official Microsoft blog post about new features in C# 7. If you have some questions about this blog in particular or you just want to "talk shop," simply comment below or send me an email!

Thanks for reading, and have a great, tuple-filled 2017!

Tags