In C# you have some built-in support for deconstructing system types and for non-supported scenarios, you can always extend your types to support that. Let’s see how to deconstruct types in C#.

Tuples have support for deconstruction which lets you unpackage all their items in a single operation.
Here is an example with and without deconstruction:

public static void Main()
{
    var result = QueryCityData("New York City");

    // Without deconstruction:
    var city = result.Item1;
    var pop = result.Item2;
    var size = result.Item3;

    // With deconstruction:
   (string city, int population, double area) = QueryCityData("New York City");
}

private static (string city, int population, double area) QueryCityData(string name)
{
    return (name, 8175133, 468.48);
}

You may be interested in the values of only some elements.
You can take advantage of C#’s support for discards, which are variables whose values you ignore by using the underscore character.
Using the previous example:

public static void Main ()
{
    // city and population were discarded.
    (, , double area) = QueryCityData("Portugal");
}

Other system types and deconstruction

Here are some system types that implement deconstruction, such as dictionary entries:

Dictionary<string,int> customerToTaxMapping = new Dictionary<string, int>();

foreach ((string key, int taxId) in customerToTaxMapping)
{
     // Do something with key and taxId
}

You can deconstruct KeyValuePair instances (depending on your C# version, was introduced in .NET Core 2.0):

(string id, string taxId) = new KeyValuePair("id", "taxId");

If you are on C# 12 (.NET 8), then you can make use of the Deconstruct methods for DateTime, DateOnly and DateTimeOffset:

(DateOnly date, TimeOnly time) = new DateTime(2023, 1, 2, 4, 5, 59, 999);

(int year, int month, int day) = new DateTime(2023, 1, 2);

(int year, int month, int day) = new DateOnly(2023, 5, 1);

// Instantiate date and time using years, months, days,
// hours, minutes, seconds and a time span.
(DateOnly date, TimeOnly time, TimeSpan offset) = new DateTimeOffset(2008, 5, 1, 8, 6, 32, new TimeSpan(1, 0, 0));

Deconstruct user-defined types:

You can add public methods named Deconstruct and specify the out parameters that will define the parameters you want when applying deconstruction.

public class Person
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

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

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

If you don’t have control over the types that you want to provide deconstruction support for, then you can create a static class with a Deconstruct extension method with the same signature as displayed previously, for that given type.

Additionally, when you declare a record type by using two or more positional parameters, the compiler creates a Deconstruct method within the record declaration.

Note: You can’t deconstruct dynamic objects.

References:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#127-deconstruction

LEAVE A REPLY

Please enter your comment!
Please enter your name here