C# ValueTuple

Exploring the C# ValueTuple type

Home DailyDrop

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.
c# .net tuple valuetuple .net6