Using Tuples in C# to Initialize Properties in the Constructor and to Deconstruct Your Object

Recently I was asked by a developer what this code block here actually is:

public Friend(string firstName, string middleName, string lastName)
  => (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);

This is actually a constructor that uses an expression body and tuples.

Since C# 7.0 you can use tuples in your code and you can also use expression bodied constructors. These two features allow you to write constructors in a more compact syntax that you see above. You see this syntax also quite often in code samples and also in the official .NET documentation.

Let’s look at it a bit more detailed. The traditional way to create a constructor and to initialize properties in a constructor looks like below:

public class Friend
{
    public Friend(string firstName, string middleName, string lastName)
    {
        FirstName = firstName;
        MiddleName = middleName;
        LastName = lastName;
    }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

Since C# 7.0, you can use tuples in the constructor. The constructor below does this. It creates a tuple with the values of the three constructor parameters and assigns it to a tuple with the three properties. That means this constructor below does exactly the same as the constructor that you see in the code snippet above: It assigns the three parameter values to the three properties FirstName, MiddleName and LastName:

public Friend(string firstName, string middleName, string lastName)
{
    (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);
}

Whenever you have a method, a property accessor, or a constructor with a single statement as the one above, it is a perfect fit to use an expression body. So, you can write the constructor like below, which is the syntax that you have seen at the beginning of this blog post:

public Friend(string firstName, string middleName, string lastName)
  => (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);

Add a Deconstruct Method to Your Class

In the code snippet below I added a Deconstruct method to the Friend class. As you can see, it returns void and it has the three out parameters firstName, middleName, and lastName. In the method body it assigns the values of the properties FirstName, MiddleName, and LastName to the three out parameters.

public class Friend
{
    public Friend(string firstName, string middleName, string lastName)
      => (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);

    public void Deconstruct(out string firstName,
      out string middleName,
      out string lastName)
    {
        firstName = FirstName;
        middleName = MiddleName;
        lastName = LastName;
    }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

With that Deconstruct method, you can deconstruct a Friend object into a tuple as shown in the code snippet below.

var friend = new Friend("Thomas", "Claudius", "Huber");

var (first, middle, last) = friend; // This calls the Deconstruct method

Console.WriteLine(first); // Thomas
Console.WriteLine(middle); // Claudius
Console.WriteLine(last); // Huber

Now, when you look in the code snippet below at the body of the Deconstruct method, you can see that it has three statements to set all the three out parameters. That’s a perfect use case for tuples.

public void Deconstruct(out string firstName,
  out string middleName,
  out string lastName)
{
    firstName = FirstName;
    middleName = MiddleName;
    lastName = LastName;
}

The code snippet below shows how to use tuples in the Deconstruct method. A tuple for the properties FirstName, MiddleName, and LastName is created and assigned to a tuple with the out parameters firstName, middleName, and lastName.

public void Deconstruct(out string firstName,
  out string middleName,
  out string lastName)
{
    (firstName ,middleName,lastName) = (FirstName,MiddleName,LastName);
}

Now, with that single statement in the Deconstruct method, you can also use an expression body like in the code snippet below.

public void Deconstruct(out string firstName,
  out string middleName,
  out string lastName)
  => (firstName, middleName, lastName) = (FirstName, MiddleName, LastName);

This leads to a more compact Friend class that looks like below.

public class Friend
{
    public Friend(string firstName, string middleName, string lastName)
      => (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);

    public void Deconstruct(out string firstName,
      out string middleName,
      out string lastName)
      => (firstName, middleName, lastName) = (FirstName, MiddleName, LastName);

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

Summary

As you’ve seen in this blog post, tuples are quite powerful to combine multiple assign statements into a single statement. And by combining tuples with expression bodies you get quite compact code that is still very readable for those who are familiar with tuples.

Happy coding,
Thomas

Share this post

Comments (6)

  • Philipp Elhaus Reply

    In ihrem WPF buch, 5te Auflage, Seite 489, bei ICommand ist in dem Code Beispiel Leerzeichen Setzung der Properties kaputt.

    March 26, 2021 at 9:00 am
    • Thomas Claudius Huber Reply

      Danke, eben nachgeschaut, stimmt. Hat beim Setzen wohl jemand die Leerzeichen aufgegessen. :) Ist allerdings immer noch gültiger C# Code, aber ja, unschön formatiert. Danke für den Hinweis.

      March 26, 2021 at 10:06 am
  • Sabit Reply

    Hello Thomas

    I see that

    public Friend(string firstName, string middleName, string lastName)
    {
    (FirstName, MiddleName, LastName) = (firstName, middleName, lastName);
    }

    turns into casual assignment

    public Friend(string firstName, string middleName, string lastName)
    {
    string text2 = (FirstName = firstName);
    text2 = (MiddleName = middleName);
    text2 = (LastName = lastName);
    }

    on sharplab : https://tinyurl.com/assignmentTuple

    May 11, 2022 at 8:45 pm
  • Snoopy Reply

    This was super clear and informative! It’s not so often you read a technical article that is as well written as this one. Learned and enjoyed reading this, I appreciate your effort and hope you continue to create material for a long time!

    December 18, 2022 at 1:36 pm
  • Vikas Reply

    Thanks, C# 7+ Tuples makes more sense now :)

    February 11, 2023 at 10:37 am

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.