Deconstructing a class instance into multiple variables

Investigating how a class instance can be easily deconstructed into multiple variables

Home DailyDrop

Daily Knowledge Drop

One or many Deconstruct methods can be added to a class allowing the class properties to be deconstructed into one or more variables (depending on the Deconstruct methods available). This helps created cleaner, more concise code.


Non-Deconstruct

Consider a Song class, with three properties:

public class Song
{
    public string SongName { get; init; }

    public string ArtistName { get; init; }

    public int LengthInSeconds { get; init; }
}

If there is a requirement to print out all the properties of a Song instance, it could be done like this:

var song1 = new Song
{
    ArtistName = "Foo Fighters",
    SongName = "Everlong",
    LengthInSeconds = 250
};

Console.WriteLine($"The song '{song1.SongName}' by '{song1.ArtistName}' " +
    $"is {song1.LengthInSeconds} seconds long");

Nothing especially wrong with this, but if the Song class had more properties, with long names, the interpolated string could get long and unwieldy.

This could be simplified by doing the following:

var song1 = new Song
{
    ArtistName = "Foo Fighters",
    SongName = "Everlong",
    LengthInSeconds = 250
};

var name = song1.SongName;
var artist = song1.ArtistName;
var length = song1.LengthInSeconds;

Console.WriteLine($"The song '{name}' by '{artist}' is {length} seconds long");

The interpolated string is definitely more concise now, but thee extra variables have been defined and assigned. This would make sense if the values are being reused numerous times in the code - but if this is only used once-off, a lot of vertical space has been taken up for no real "value".

However, the Deconstruct method makes this process even more concise and simpler.


Deconstruct

One or many Deconstruct method can be added to the Song class to allow for the deconstruction of the instance into variables.

A method called Deconstruct is defined on the class, with one or more out parameters in the method signature:

public class Song
{
    public string SongName { get; init; }

    public string ArtistName { get; init; }

    public int LengthInSeconds { get; init; }

    // deconstruct all three properties
    public void Deconstruct(out string artist, out string name, out int length)
    {
        name = SongName;
        artist = ArtistName;
        length = LengthInSeconds;
    }

    // deconstruct into a string combination of song and artist
    // as well as the length
    public void Deconstruct(out string output, out int length)
    {
        output = $"'{SongName}' by {ArtistName}";
        length = LengthInSeconds;
    }
}

The Deconstruct methods can now be used as follows:

var song1 = new Song
{
    ArtistName = "Foo Fighters",
    SongName = "Everlong",
    LengthInSeconds = 250
};

// deconstruct song1, into three variables
var (artist, name, length) = song1;
Console.WriteLine($"The song '{name}' by '{artist}' is {length} long");

Here, the three variables artist, name and length are automatically defined and assigned to the out parameter values of the matching corresponding Deconstruct method. Definitely cleaner and more concise that previous techniques.

The Deconstruct methods also work with the discard character. In the above example there is a second Deconstruct method which returns the string output and the song length. If only interested in the output value, but not the length, then the following can be done:

var song1 = new Song
{
    ArtistName = "Foo Fighters",
    SongName = "Everlong",
    LengthInSeconds = 250
};

// deconstruct song1, into only one variable
// discarding the length
var (output, _) = song1;
Console.WriteLine(output);

Here no memory is allocated for the length out parameter where the discard is used.


Notes

There are not too many practical use cases for the Deconstruct method - but where it can be applied (in cases such as the ones described above), it will definitely assist with creating cleaner, more concise code.


References

Deconstructing tuples and other types


Daily Drop 127: 29-07-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net deconstruct tuple