Page 21 - MSDN Magazine, June 2018
P. 21

.NET FRAMEWORK
Tuple Trouble:
Why C# Tuples Get to
Break the Guidelines
Mark Michaelis
Back in the August 2017 issue of MSDN Magazine I wrote an in-depth article on C# 7.0 and its support for tuples (msdn.com/ magazine/mt493248). At the time I glossed over the fact that the tuple type introduced with C# 7.0 (internally of type ValueTuple<...>) breaks several guidelines of a well-structured value type, namely:
• Do Not declare fields that are public or protected (instead encapsulate with a property).
• Do Not define mutable value types.
• Do Not create value types larger than 16 bytes in size. These guidelines have been in place since C# 1.0, and yet here in C# 7.0, they’ve been thrown to the wind to define the System.Value- Tuple<...> data type. Technically, System.ValueTuple<...> is a family of data types of the same name, but of varying arity (specifi- cally, the number of type parameters). What’s so special about this particular data type that these long-respected guidelines no longer apply? And how can our understanding of the circumstances in which these guidelines apply—or don’t apply—help us refine their
application to defining value types?
Let’s start the discussion with a focus on encapsulation and the benefits of properties versus fields. Consider, for example, an Arc value type representing a portion of the circumference of a circle. It’s defined by the radius of the circle, the start angle (in degrees) of the first point in the arc, and the sweep angle (in degrees) of the last point in the arc, as shown in Figure 1.
Do Not Declare Fields That Are Public or Protected In this declaration, Arc is a value type (defined using the keyword struct) with three public fields that define the characteristics of the Arc. Yes, I could’ve used properties, but I chose to use public fields in this example specifically because it violates the first guideline— Do Not declare fields that are public or protected.
By leveraging public fields rather than properties, the Arc definition lacks the most basic of object-oriented design principles— encapsulation. For example, what if I decided to change the internal data structure to use the radius, start angle and arc length, for example, rather than the sweep angle? Doing so would obvi- ously break the interface for Arc and all clients would be forced to make a code change.
Similarly, with the definitions of Radius, StartAngle and Sweep- Angle, I have no validation. Radius, for example, could be assigned a negative value. And while negative values for StartAngle and SweepAngle might be allowable, a value greater than 360 degrees wouldn’t. Unfortunately, because Arc is defined using public fields, there’s no way to add validation to protect against these values. Yes, I could add validation in version 2 by changing the fields to prop- erties, but doing so would break the version compatibility of the
This article discusses:
• Guidelines for programming value types (structs)
• How to use C# 7.0 tuples to override Equals and GetHashCode
• Understanding Guidelines are just tha—they still allow for coloring outside the lines given sufficient justification
Technologies discussed:
C# 7.0, Microsoft .NET Core/Framework, Tuples
June 2018 15


































































































   19   20   21   22   23