C# – How to deconstruct an object

Deconstructing an object means assigning its properties to several variables with a one-liner using deconstruction assignment syntax (also referred to as destructuring or unpacking). Here’s an example of deconstructing an object:

var coder = new Coder()
{
    Name = "Bob",
    Language = "C#",
    YearsExperience = 5
};

var (name, lang) = coder;

Console.WriteLine($"{name} is a {lang} coder");
Code language: C# (cs)

This outputs the following:

Bob is a C# coderCode language: plaintext (plaintext)

Several built-in types already support deconstruction – such as tuples, dictionary (KeyValuePair), and records. You can enable deconstruction for any type by adding the Deconstruct() method. I’ll show examples below.

Add the Deconstruct() method

Here’s an example of adding the Deconstruct() method to a class (note: this is the Coder class from the example up above):

public class Coder
{
    public string Name { get; set; }
    public string Language { get; set; }
    public int YearsExperience { get; set; }

    public void Deconstruct(out string name, out string language)
    {
        name = Name;
        language = Language;
    }
}
Code language: C# (cs)

The Deconstruct() method definition is based purely on convention. When you use the deconstruction assignment syntax on a type, the compiler looks for the Deconstruct() method. It doesn’t come from an interface or anything like that. There are three requirements to implementing this method:

  • Name it Deconstruct.
  • Make it void.
  • Add multiple out parameters. These are output during deconstruction.

Now this type can be used with the deconstruction assignment syntax, like this:

var (name, lang) = coder;
Code language: C# (cs)

Behind the scenes, this syntax sugar is really doing the following:

string name;
string language;
coder.Deconstruct(out name, out language);
Code language: C# (cs)

Multiple Deconstruct() methods

You can add multiple Deconstruct() methods to a type. This is useful for enabling deconstruction assignment with different combinations of properties. Here’s an example of adding two Deconstruct() methods:

public class Coder
{
    public string Name { get; set; }
    public string Language { get; set; }
    public int YearsExperience { get; set; }

    public void Deconstruct(out string name, out string language)
    {
        name = Name;
        language = Language;
    }
    public void Deconstruct(out string name, out string language, out int yearsExperience)
    {
        name = Name;
        language = Language;
        yearsExperience = YearsExperience;
    }
}
Code language: C# (cs)

Both of these Deconstruct() methods can be used with deconstruction assignment:

var (name, lang) = coder;

var (name2, lang2, years) = coder;
Code language: C# (cs)

Error CS8130 – Can’t infer deconstruction types

If you have two Deconstruct() methods with the same number of parameters, the compiler can’t infer the types in the deconstruction assignment (error CS8130). In this case, you have to explicitly declare the types, like this:

(string name, string lang) = coder;
Code language: C# (cs)

Add Deconstruct() as an extension method

Besides implementing Deconstruct() in your own types, you can add Deconstruct() as an extension method to be able to deconstruct any type. Here’s an example:

public static class PersonExtensions
{
    public static void Deconstruct(this Person person, out string firstName, out string lastName)
    {
        firstName = person.FirstName;
        lastName = person.LastName;
    }
}
Code language: C# (cs)

Now this type can be used with deconstruction:

var person = new Person()
{
    FirstName = "Bob",
    LastName = "Smith"
};

var (first, last) = person;
Code language: C# (cs)

A type can have multiple Deconstruct() implementations. So even if a class has a Deconstruct() method already, you can add your own extension method to get exactly the properties you want in deconstruction.