ZetCode

C# deconstruct

last modified July 18, 2023

C# deconstruct tutorial shows how to perform deconstructing operation: unpacking variables from types in C#.

Deconstructing is unpacking types into single pieces; for instance, a tuple into its items or a class into its properties.

C# deconstruct tuple

In the next example we deconstruct tuples into items.

tuple_dec.csx
var user = ("John", "Doe", "gardener");

var (firstName, lastName, occupation) = user;

Console.WriteLine(firstName);
Console.WriteLine(lastName);
Console.WriteLine(occupation);

Console.WriteLine("-----------------");

var (fn, ln, oc) = getUser();

Console.WriteLine(fn);
Console.WriteLine(ln);
Console.WriteLine(oc);


(string, string, string) getUser()
{
    var fname = "John";
    var lname = "Doe";
    var occupation = "gardener";
    
    return (fname, lname, occupation);
}

A user tuple has three items; these items are unpacked into separate variables.

var (firstName, lastName, occupation) = user;

Here, we perform the deconstructing operation;

$ dotnet-script tuple_dec.csx 
John
Doe
gardener
-----------------
John
Doe
gardener

Discards can be used for items that are not needed.

discards.csx
var user = ("John", "Doe", "gardener");
var (fname, lname, _) = user;

Console.WriteLine($"{fname} {lname}")

In this program, we use a discard for the third value.

C# deconstruct dictionary

A dictionary consists of key/value pairs. These pairs can be unpacked into two separate variables.

dict_dec.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

foreach ((string k, string v) in domains)
{
    Console.WriteLine($"{k}: {v}");
}

In a foreach loop, we unpack each pair into k and v variables.

$ dotnet-script dict_dec.csx 
sk: Slovakia
ru: Russia
de: Germany
no: Norway

C# deconstruct class

To deconstruct classes, we have to implement the Deconstruct method.

class_dec.csx
var u = new User("John", "Doe", "gardener");
var (fname, lname, occupation) = u;

Console.WriteLine($"{fname} {lname} is a(n) {occupation}");

var (fn, ln) = u;
Console.WriteLine($"{fn} {ln}");


class User
{
    string FirstName { get; set; }
    string LastName { get; set; }
    string Occupation { get; set; }

    public User(string fname, string lname, string occupation)
    {
        FirstName = fname;
        LastName = lname;
        Occupation = occupation;
    }

    public void Deconstruct(out string fname, out string lname)
    {
        fname = FirstName;
        lname = LastName;
    }

    public void Deconstruct(out string fname, out string lname, 
        out string occupation)
    {
        fname = FirstName;
        lname = LastName;
        occupation = Occupation;
    }
}

We can have multiple Deconstruct methods.

var u = new User("John", "Doe", "gardener");
var (fname, lname, occupation) = u;

Here, we deconstruct the User type into three variables.

var (fn, ln) = u;
Console.WriteLine($"{fn} {ln}");

Here, we deconstruct the user into two variables.

public void Deconstruct(out string fname, out string lname)
{
    fname = FirstName;
    lname = LastName;
}

The variables that are deconstructed have the out modifier.

$ dotnet-script class_dec.csx 
John Doe is a(n) gardener
John Doe

C# deconstruct record

Record types with positional parameters are automatically deconstructed; the compiler creates the Deconstruct method for us.

record_dec.csx
var user = new User("John", "Doe", "gardener");
var (firstName, lastName, occupation) = user;

Console.WriteLine($"{firstName} {lastName} is a(n) {occupation}");

record User(string FirstName, string LastName, string Occupation);

In the example, we unpack the User record.

C# deconstruct extension method

In the next example, we create a Deconstruct extension method.

Program.cs
var dt = new DateTime(2021, 9, 16);
(int year, int month, int day) = dt;

Console.WriteLine(year);
Console.WriteLine(month);
Console.WriteLine(day);

public static class MyExtension
{
    public static void Deconstruct(this DateTime dateTime, out int year,
        out int month, out int day)
    {
        year = dateTime.Year;
        month = dateTime.Month;
        day = dateTime.Day;
    }
}

The program defines a Deconstruct method for the DateTime type; it unpacks the type into its year, month, and day parts.

$ dotnet run
2021
9
16

Source

Deconstructing tuples and other types

In this article we have worked with deconstructing operations in C#.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all C# tutorials.