When C# burst on to the scene at the turn of the century I was firmly embedded in the world of Visual Basic and C++, these two languages were fulfilling vastly different jobs for me. I was using C++ to create a high performance multi-threaded application, but with VB I was able to churn out high quality Windows Form applications. The promise of C#, however, was a language that would allow you to accomplish both. I was in Detroit for that first C# presentation and the way it is was presented reminded me of a famous Bruce Lee quote:

"You must be shapeless, formless, like water. When you pour water in a cup, it becomes the cup. When you pour water in a bottle, it becomes the bottle. When you pour water in a teapot, it becomes the teapot. Water can drip and it can crash. Become like water my friend."

C# is incredibly versatile and there are a multitude of disciplines it naturally flows into, supporting technologies that include web development, IoT, Cloud, Gaming, and so many, many more. This diversity of application necessitates careful stewardship of the language direction, so every time there are new features I like to take inventory of how it might otherwise improve or regress the language. To that end I am openly curious about the proposed changes to tuples.

Tuples

Tuples have always been a very useful but curious type, they exist as a mutable struct that have a specific number and sequence of elements. In the .NET framework the Tuple class does not directly represent a tuple but simply provides convenient constructors and methods to create tuples.

The two ways I would find acceptable to use tuples are when I want to return a couple of simple value types from a single method:

static Tuple<int, string, string> GetHumanData()
{
    return Tuple.Create(10, "Marcus", "Miller");
}

I would also use tuples in scenarios where I wanted to temporarily associate two or more complex but related data objects. I have known many developers who would not deign to use tuples in any of these scenarios and here is the main reason why. The Tuple returned in the method above looks like this:

var data = GetHumanData();
Console.WriteLine("What is this value {0} or this {1}",
    data.Item1, data.Item3);

In terms of naming conventions the members Item1 and Item3 are completely meaningless. Developers reading this code can infer almost nothing from the usage and are forced to look back at the Tuple creation points for clues about them. Using classes is the most obvious solution but would add to the costs of allocation. Structs, however, are by design really efficient mechanisms for combining multiple values and objects together but semantically look awful (as Item[n]).

Tuple changes in C# 7

With my reservations for tuples duly noted there is some important improvements included in C# 7 and Visual Studio 2017 that I think deserve a little more reflection. After installing VS 2017 RC go to the NuGet Package manager and search for "Tuple" and install System.ValueTuple and associate it with your project.

So here is my method rewritten with the new tuple syntax, essentially removing the tuple constructor:

public (int, string, string) GetHumanData()
{
    return Tuple.Create(57, "Marcus", "Miller");
}

That is a nice shorthand but what I really like is how you can now define tuple members with much more meaningful names as in the following:

(int Age, string FirstName, string LastName) result = GetHumanData();
Console.WriteLine(result.Age);
Console.WriteLine(result.FirstName);
Console.WriteLine(result.LastName);

This is a welcome change, that looks to be backwards compatible while it opens up inline data types in a much more thorough way.



February 15, 2017 6:55  Comments [3]
Tagged in .NET | C#
Share on Twitter, Facebook and Google+