Page 80 - MSDN Magazine, August 2017
P. 80

to the implicitly typed variable, however, so they’re still available for the WriteLine statement. Of course, this opens the possibility that you could name the items on the left-hand side with names that are different from those you use on the right. While the C# compiler allows this, it will issue a warning that the item names on the right will be ignored as those on the left take precedence.
If no item names are specified, the individual elements are still available from the assigned tuple variable. However, the names are Item1, Item2 and so on, as shown in example 7. In fact, the ItemX name is always available on the tuple—even when custom names are provided (see example 8). However, when using IDE tools like any of the recent flavors of Visual Studio that support C# 7.0, the ItemX property will not appear within the IntelliSense dropdown—a good thing because presumably the provided name is preferable.
As shown in example 9, portions of a tuple assignment can be
are no properties for ItemX, but rather read-write fields (seemingly breaking the most basic of .NET Programming Guidelines as explained at itl.tc/CS7TuplesBreaksGuidelines).
In addition to the programming guidelines discrepancy, there’s another behavioral question that arises. Given that the custom item names and their types aren’t included in the System.Value- Tuple<...> definition, how is it possible that each custom item name is seemingly a member of the System.ValueTuple<...> type and accessible as a member of that type?
What’s surprising (particularly for those familiar with the anon- ymous type implementation) is that the compiler doesn’t generate underlying Common Intermediate Language (CIL) code for the members corresponding to the custom names. However, even without an underlying member with the custom name, there is (seemingly) from the C# perspective, such a member.
excluded using an underscore; this is called a discard.
Tuples are a lightweight solution for encapsulating data into a single object in the same way that a bag might capture miscellaneous items you pick up from the store. Unlike arrays, tuples contain item data types that can vary virtually without constraint (although pointers aren’t allowed), except that they’re identi- fied by the code and can’t be changed at run time. Also, unlike with arrays, the number of items within the tuple is hardcoded at compile time, as well. Last, you can’t add custom behavior to a tuple (extension meth- ods notwithstanding). If you need behavior associated with the encap- sulated data, then leveraging object- oriented programing and defining a class is the preferred approach.
The System.ValueTuple<...>
Type
The C# compiler generates code that relies on a set of generic value types (structs), such as System.Value- Tuple<T1, T2, T3>, as the underlying implementation for the tuple syntax for all tuple instances on the right- hand side of the examples in Figure 1. Similarly, the same set of System.ValueTuple<...> generic value types is used for the left-hand-side data type starting with example 5. As you’d expect with a tuple type, the only methods included are those related to comparison and equality. However, perhaps unexpectedly, there
Figure 1 Sample Code for Tuple Declaration and Assignment
Example
Description
Example Code
1.
Assigning a tuple to individually declared variables.
(string country, string capital, double gdpPerCapita) = ("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
country}, {capital}: {gdpPerCapita}");
2.
Assigning a tuple to individually declared variables that are pre-declared.
string country; string capital; double gdpPerCapita;
(country, capital, gdpPerCapita) = ("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
country}, {capital}: {gdpPerCapita}");
3.
Assigning a tuple to individually declared and implicitly typed variables.
(var country, var capital, var gdpPerCapita) = ("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
country}, {capital}: {gdpPerCapita}");
4.
Assigning a tuple to individually declared variables that are implicitly typed with a distributive syntax.
var (country, capital, gdpPerCapita) = ("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
country}, {capital}: {gdpPerCapita}");
5.
Declaring a named item tuple and assigning it tuple values and then accessing the tuple items by name.
(string Name, string Capital, double GdpPerCapita) countryInfo = ("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
countryInfo.Name}, {countryInfo.Capital}: { countryInfo.GdpPerCapita}");
6.
Assigning a named item tuple to a single implicitly typed variable that’s implicitly typed and then accessing the tuple items by name.
var countryInfo =
(Name: "Malawi", Capital: "Lilongwe", GdpPerCapita: 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
countryInfo.Name}, {countryInfo.Capital}: { countryInfo.GdpPerCapita}");
7.
Assigning an unnamed tuple to a single implicitly typed variable and then accessing the tuple elements by their Item-number property.
var countryInfo =
("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
countryInfo.Item1}, {countryInfo.Item2}: { countryInfo.Item3}");
8.
Assigning a named item tuple to a single implicitly typed variable and then accessing the tuple items by their Item-number property.
var countryInfo =
(Name: "Malawi", Capital: "Lilongwe", GdpPerCapita: 226.50);
System.Console.WriteLine(
$@"The poorest country in the world in 2017 was {
countryInfo.Item1}, {countryInfo.Item2}: { countryInfo.Item3}");
9.
Discard portions of the tuple with underscores.
(string name, _, double gdpPerCapita) countryInfo = ("Malawi", "Lilongwe", 226.50);
74 msdn magazine
Essential .NET



























   78   79   80   81   82