Page 81 - MSDN Magazine, August 2017
P. 81

For all the named tuple local variable examples, for example:
var countryInfo = (Name: "Malawi", Capital: "Lilongwe", GdpPerCapita: 226.50)
it’s clearly possible that the names could be known by the compiler for the remainder of the scope of the tuple because that scope is bounded within the member in which it’s declared. And, in fact, the compiler (and IDE) quite simply rely on this scope to allow accessing each item by name. In other words, the compiler looks at the item names within the tuple declaration and leverages them to allow code that uses those names within the scope. It’s for this reason, as well, that the ItemX methods aren’t shown in the IDE IntelliSense as available members on the tuple (the IDE simply ignores them and replaces them with the named items).
Determining the item names from when scoped within a mem- ber is reasonable for the compiler, but what happens when a tuple is exposed outside the member—such as a parameter or return from a method that’s in a different assembly (for which there’s possibly no source code available)? For all tuples that are part of the API (whether a public or private API), the compiler adds item names to the metadata of the member in the form of attributes. For example, this:
[return: System.Runtime.CompilerServices.TupleElementNames( new string[] {"First", "Second"})]
public System.ValueTuple<string, string> ParseNames(string fullName) {
// ... }
is the C# equivalent of what the compiler generates for the following:
public (string First, string Second) ParseNames(string fullName)
On a related note, C# 7.0 doesn’t enable the use of custom item names when using the explicit System.ValueTuple<...> data type. Therefore, if you replace var in Example 8 of Figure 1, you’ll end up with warnings that each item name will be ignored.
Here are a few additional miscellaneous facts to keep in mind about System.ValueTuple<...>:
• There are a total of eight generic System.ValueTuple structs corresponding to the possibility of supporting a tuple with up to seven items. For the eighth tuple, System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>, the last type parameter allows specifying an additional value tuple, thus enabling support for n items. If, for example, you specify a tuple with 8 parameters, the compiler will automatically generate a System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, System.Value- Tuple<TSub1>> as the underlying implementing type. (For completeness, System.Value<T1> exists, but will really only be used directly and only as a type. It will never be used directly by the compiler because the C# tuple syntax requires a minimum of two items.)
• There is a non-generic System.ValueTuple that serves as a tuple factory with Create methods corresponding to each value tuple arity. The ease of using a tuple literal, such as var t1 = (“Inigo Montoya”, 42), supersedes the Create method at least for C# 7.0 (or later) programmers.
• For all practical purposes, C# developers can essentially ignore System.ValueTuple and System.ValueTuple<T>.
There’s another tuple type that was included with the .NET Framework 4.5—System.Tuple<...>. At that time, it was expected to be the core tuple implementation going forward. However, once C# supported tuple syntax, it was realized that a value type generally performed better and so System.ValueTuple<...> was introduced, effectively replacing System.Tuple<...> in all cases except for backward compatibility with existing APIs that depend on System.Tuple<...>.
Wrapping Up
What many folks didn’t realize when it was first introduced is that the new C# 7.0 tuple all but replaces anonymous types—and provides additional functionality. Tuples can be returned from methods, for example, and the item names are persisted in the API such that meaningful names can be used in place of ItemX type naming. And, like anonymous types, tuples can even repre- sent complex hierarchical structures such as those that might be constructed in more complex LINQ queries (albeit, like with anonymous types, developers should do this with caution). That said, this could possibly lead to situations where the tuple value type exceeds 128 bytes and, therefore, might be a corner case for when to use anonymous types because it’s a reference type. Except for these corner cases (accessing via typical reflection might be another example), there’s little to no reason to use an anonymous type when programming with C# 7.0 or later.
The ability to program with a tuple type object has been around for a long time (as mentioned, a tuple class, System.Tuple<...>, was introduced with the .NET Framework 4, but was available in Silverlight before that). However, these solutions never had an accompanying C# syntax, but rather nothing more than a .NET API. C# 7.0 brings a first-class tuple syntax that enables literals— like var tuple = (42, “Inigo Montoya”)—implicit typing, strong typing, public API utilization, integrated IDE support for named ItemX data and more. Admittedly, it might not be something you use in every C# file, but it’s likely something you’ll be grateful to have when the need arises and you’ll welcome the tuple syntax over the alternative out parameter or anonymous type.
Much of this article derives from my “Essential C#” book (IntelliTect.com/EssentialCSharp), which I’m currently in the midst of updating to “Essential C# 7.0.” For more information on this topic, check out Chapter 3. n
Mark Michaelis is founder of IntelliTect, where he serves as its chief technical architect and trainer. For nearly two decades he’s been a Microsoft MVP, and a Microsoft Regional Director since 2007. Michaelis serves on several Micro­ soft software design review teams, including C#, Microsoft Azure, SharePoint and Visual Studio ALM. He speaks at developer conferences and has written numerous books, including his most recent, “Essential C# 6.0 (5th Edition)” (itl.tc/­ EssentialCSharp). Contact him on Facebook at facebook.com/Mark.Michaelis, on his blog at IntelliTect.com/Mark, on Twitter: @markmichaelis or via e­mail at mark@IntelliTect.com.
Thanks to the following Microsoft technical expert for reviewing this article: Mads Torgersen
TUPLE ITEM NAMING GUIDELINES
Do use camelCase for all variables declared using tuple syntax. Consider using PascalCase for all tuple item names.
msdnmagazine.com
August 2017 75










































































   79   80   81   82   83