Daily Knowledge Drop
You may have heard of C# the Tuple
type, but there is also a ValueTuple
type available, which has existed in C# since .NET 4.7!
The post will will take a brief look at the Tuple
type and compare its functionality to that of the ValueTuple
type.
Tuple
Tuple usage
A Tuple is a data structure which has a specific number and sequence of elements
. The data structure can contain up to 8 elements, but if more are required, nested tuple objects can be leveraged in the 8th element to extent the number of elements.
It is an effective, quick and simple way to create an immutable data entity structure without creating an entire class entity.
What do I mean by this?
Assume you have a method which needs to return a number of details related to a person. The go to solution would be to create a Person class with the relevant properties and return an instance of the class from the method.
If this class is only going to be used in one place, it might not make sense for an entire class to be defined - in this case a Tuple
can be used instead.
The following example uses .NET6 C# console application with minimal startup:
// Invoke the method and get the tuple back
var personInfo = GetPersonInformation();
// Each element in the tuple can be accessed
// The elements in the Tuple are accessed using
// the `ItemX` property, which corresponds to the element in position X
Console.WriteLine(personInfo.Item1);
Console.WriteLine(personInfo.Item2);
Console.WriteLine(personInfo.Item3);
Console.WriteLine(personInfo);
static Tuple<string, string, int> GetPersonInformation()
{
return new Tuple<string, string, int>("Dave", "Grohl", 53);
}
The output is as follows:
Dave
Grohl
53
(Dave, Grohl, 53)
Tuple creation
In the above example, the Tuple
was created and returned using the constructor method. These is another way - the static Tuple.Create
method.
// Using a generic constructor
var constructorTuple = new Tuple<string, string, int>("Dave", "Grohl", 53);
// Using the static Tuple Create method
var createTuple = Tuple.Create("Dave", "Grohl", 53);
Both are equivalent, however the Create method is easier to use when dealing with nested Tuples.
ValueTuple
ValueTuple usage
A ValueTuple
operations the same as a Tuple
on the surface, but there are a number of key differences between the two.
- ValueTuple is a struct (a value type), while a Tuple is a class (a reference type)
- ValueTuple is mutable (can be changed), while a Tuple is immutable (they are read-only)
- ValueTuple data members are fields, while Tuple data members are properties.
In the above example, Tuple
can be replaced with ValueTuple
and the code will still execute as before, with the same output:
var personInfo = GetPersonInformation();
Console.WriteLine(personInfo.Item1);
Console.WriteLine(personInfo.Item2);
Console.WriteLine(personInfo.Item3);
Console.WriteLine(personInfo);
static ValueTuple<string, string, int> GetPersonInformation()
{
return new ValueTuple<string, string, int>("Dave", "Grohl", 53);
}
In addition to the differences mentioned above, the ValueTuple
also has additional ways in which it can be created, which allows working with the elements much easier.
ValueTuple creation
As seen above a ValueTuple
can be created using the constructor:
var consValueTuple = new ValueTuple<string, string, int>("Dave", "Grohl", 53);
It can also be created using the static Create method:
var createValueTuple = ValueTuple.Create("Dave", "Grohl", 53);
In addition it can be created as follows
var valueTuple = ("Dave", "Grohl", 53);
In all three of the above, the elements are still accessed using the Item1, Item2, etc properties. With a ValueTuple
it is possible to give each element a name and access it by name.
Instead of using the var keyword, we explicitly define the ValueTuple types, with names.
(string FirstName, string LastName, int Age) nameValueTuple = ("Dave", "Grohl", 53);
// The elements can now be accessed by name
Console.WriteLine(nameValueTuple.FirstName);
Console.WriteLine(nameValueTuple.LastName);
Console.WriteLine(nameValueTuple.Age);
Console.WriteLine(nameValueTuple);
// This will also still also work
Console.WriteLine(nameValueTuple.Item1);
Console.WriteLine(nameValueTuple.Item2);
Console.WriteLine(nameValueTuple.Item3);
Any of the three initialization methods can be used to create the a ValueTuple
with names.
/// Create using the constructor
(string FirstName, string LastName, int Age) consValueTuple =
new ValueTuple<string, string, int>("Dave", "Grohl", 53);
// Create using the static method
(string FirstName, string LastName, int Age) createValueTuple =
ValueTuple.Create("Dave", "Grohl", 53);
// Create using the abbreviated syntax
(string FirstName, string LastName, int Age) valueTuple = ("Dave", "Grohl", 53);
A named ValueTuple can also be returned from a method:
var personInfo = GetPersonInformation();
// now accessed by name
Console.WriteLine(personInfo.FirstName);
Console.WriteLine(personInfo.LastName);
Console.WriteLine(personInfo.Age);
Console.WriteLine(personInfo);
static (string FirstName, string LastName, int Age) GetPersonInformation()
{
return ("Dave", "Grohl", 53);
}
Notes
Today we looked at the Tuple
and ValueTuple
structures, how they are different and the various ways they can be initialized.
For additional reading, see the references below.
References
Tuple Class
ValueTuple Class
Tuple in C#
Daily Drop 05: 07-02-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.