Doubtlessly, while developing programs, you will have designed and implemented classes, and more often than not, these classes have had constructors.

A constructor is a special method that is used to create an object and initialize its state.

Take the following class:

public sealed class Spy
{
    public Spy(string firstName, string surname, DateOnly dateOfBirth)
    {
        FirstName = firstName;
        Surname = surname;
        DateOfBirth = dateOfBirth;
    }

    public string FirstName { get; }
    public string Surname { get; }
    public DateOnly DateOfBirth { get; }
}

Here is a simple program that creates a class:

using Serilog;

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

var spy = new Spy("James", "Bond", new DateOnly(1950, 1, 1));

Log.Information("The first name is {FirstName}", spy.FirstName);
Log.Information("The surname name is {Surname}", spy.Surname);
Log.Information("The date of birth is {DateOfBirth}", spy.DateOfBirth);

This, unsurprisingly, will print the following:

DeconstructOld

Of interest is the fact that we need to extract each of the components of the Spy so that we can use them in some way.

Is there an easier way to get these values? There is - the object deconstructor.

We can update our class as follows:

public sealed class Spy
{
    public Spy(string firstName, string surname, DateOnly dateOfBirth)
    {
        FirstName = firstName;
        Surname = surname;
        DateOfBirth = dateOfBirth;
    }

    public string FirstName { get; }
    public string Surname { get; }
    public DateOnly DateOfBirth { get; }

    public void Deconstruct(out string firstName, out string surname, out DateOnly dateOfBirth)
    {
        firstName = FirstName;
        surname = Surname;
        dateOfBirth = DateOfBirth;
    }
}

Notice the new method we have added - Deconstruct. As you can see, it is a void method that returns data via out parameters.

We use the Deconstruct method as follows:

string firstName;
string surname;
DateOnly dateOfBirth;

(firstName, surname, dateOfBirth) = spy;

Log.Information("The first name is {FirstName}", firstName);
Log.Information("The surname name is {Surname}", surname);
Log.Information("The date of birth is {DateOfBirth}", dateOfBirth);

You can simplify this still further as follows:

var (firstName, surname, dateOfBirth) = spy;

Log.Information("The first name is {FirstName}", firstName);
Log.Information("The surname name is {Surname}", surname);
Log.Information("The date of birth is {DateOfBirth}", dateOfBirth);

You can also do it like this:

(string firstName, string surname, DateOnly dateOfBirth) = spy;

Log.Information("The first name is {FirstName}", firstName);
Log.Information("The surname name is {Surname}", surname);
Log.Information("The date of birth is {DateOfBirth}", dateOfBirth);

Suppose, for whatever reason, we did not care about the date of birth despite it being factored into the deconstructor.

We can ignore it or any members we are not interested in from the deconstruction by using the discard.

var (firstName, surname, _) = spy;

Log.Information("The first name is {FirstName}", firstName);
Log.Information("The surname name is {Surname}", surname);

If your type is a record, and you use the positional syntax, a deconstructor is automatically generated for you by the compiler.

Take the following example:

public record Agency(string Name, string Motto, DateOnly DateFounded);

We can create a simple program as follows:

var agency = new Agency("Central Intelligence Agency", "The work of a nation the center of intelligence",
    new DateOnly(1947, 9, 18));

We can extract the properties as follows:

var (name, motto, dateFounded) = agency;

Log.Information("The agency name is {Name}, founded in {DateFounded}", name, dateFounded);
Log.Information("The motto is {Motto}", motto);

This will print the following:

DeconstructNew

Notice that we did not need to write our own deconstructor.

TLDR

Object deconstructors allow you to extract the properties of an object into its constituent parameters.

The code is in my GitHub.

Happy hacking!