Page 78 - MSDN Magazine, August 2017
P. 78

EssEntial .nEt MARK MICHAELIS C# 7.0: Tuples Explained
Back in November, in the Connect(); special issue, I provided an overview of C# 7.0 (msdn.microsoft.com/magazine/mt790178), in which I introduced tuples. In this article, I delve into tuples again, covering the full breadth of the syntax options.
To begin, let’s consider the question: Why tuples? On occasion, you’ll likely find it useful to combine data elements. Suppose, for example, you’re working with information about countries, such as the poorest country in the world in 2017: Malawi, whose capital is Lilongwe, with a gross domestic product (GDP) per capita of $226.50. You could obviously declare a class for this data, but it doesn’t really represent your typical noun/object. It’s seemingly more a collection of related pieces of data than it is an object. Surely, if you were going to have a Country object, for example, it would have considerably more data than just properties for the Name, Capital and GDP per capita. Alternatively, you could store each data element in individual variables, but the result would be no association between the data elements; $226.50 would have no association with Malawi except perhaps by a common suffix or prefix in the variable names. Another option would be to com- bine all the data into a single string—with the disadvantage that to work with each data element individually would require parsing it out. A final approach might be to create an anonymous type, but that, too, has limitations; enough, in fact, that tuples could potentially replace anonymous types entirely. I’ll leave this topic until the end of the article.
The best option might be the C# 7.0 tuple, which, at its simplest, provides a syntax that allows you to combine the assignment of multiple variables, of varying types, in a single statement:
(string country, string capital, double gdpPerCapita) = ("Malawi", "Lilongwe", 226.50);
In this case, I’m not only assigning multiple variables, but declaring them as well.
However, tuples have several other additional syntax possibilities, each shown in Figure 1.
In the first four examples, and although the right-hand side rep- resents a tuple, the left-hand side still represents individual variables that are assigned together using tuple syntax, which involves two or more elements separated by commas and associated with parenthe- ses. (I use the term tuple syntax because the underlying data type the compiler generates on the left-hand side isn’t technically a tuple.) The result is that although I start with values combined as a
tuple on the right, the assignment to the left deconstructs the tuple into its constituent parts. In example 2, the left-hand-side assign- ment is to pre-declared variables. However, in examples 1, 3 and 4, the variables are declared within the tuple syntax. Given that I’m only declaring variables, the naming and casing convention follows the generally accepted Framework Design Guidelines—“Do usecamelCaseforlocalvariablenames,”forexample.
Note that although implicit typing (var) can be distributed across each variable declaration within the tuple syntax, as shown in example 4, you can’t do the same with an explicit type (such as string). In this case, you’re actually declaring a tuple type, not just using tuple syntax and, therefore, you’ll need to add a reference to the System.ValueType NuGet package—at least until .NET Stan- dard 2.0. Because tuples allow each item to be a different data type, distributing the explicit type name across all elements wouldn’t necessarily work unless all the item data types were identical (and even then, the compiler doesn’t allow it).
In example 5, I declare a tuple on the left-hand side and then assign the tuple on the right. Note that the tuple has named items—names you can then reference to retrieve the item values back out of the tuple. This is what enables the countryInfo.Name, countryInfo.Capital, and countryInfo.GdpPerCapita syntax in the System.Console.WriteLine statement. The result of the tuple declaration on the left is a grouping of the variables into a single variable (countryInfo) from which you can then access the con- stituent parts. This is useful because you can then pass this single variable around to other methods and those methods will also be able to access the individual items within the tuple.
As already mentioned, variables defined using tuple syntax use camelCase. However, the convention for tuple item names isn’t well-defined. Suggestions include using parameter-naming con- ventions when the tuple behaves like a parameter —such as when returning multiple values that before tuple syntax would’ve used out parameters. The alternative is to use PascalCase, following the naming convention for public fields and properties. I strongly favor the latter approach in accordance with the Capitalization Rules for Identifiers (itl.tc/caprfi). Tuple item names are rendered as members of the tuple and the convention for all (public) members (which are potentially accessed using a dot operator) is PascalCase.
Example 6 provides the same functionality as example 5, although it uses named tuple items on the right-hand side tuple value and an implicit type declaration on the left. The items’ names are persisted
Code download available at itl.tc/MSDN.2017.08.
72 msdn magazine




















































































   76   77   78   79   80