How-To's

Generate deconstructors with ReSharper

With C# 7 came language support for deconstructing tuples and other types.

ReSharper 2017.3 Early Access Program adds better support for deconstructors, including new inspections and generators. But before diving into how ReSharper can help with writing deconstructors, let’s cover what they are.

A deconstructor allows us to easily return tuple values from a method, and makes it easier to transform e.g. a Version object into major, minor and patch variables based on usage:

var version = new Version(2, 1, 0);

// Get just the major and minor
(int major, int minor) = version;

// Get major, minor and patch
(int major, int minor, int patch) = version;

This is made possible by adding a deconstructor: one or more method(s) named Deconstruct, returning one or more out variables:

public class Version
{
    public int Major { get; }
    public int Minor { get; }
    public int Patch { get; }

    public void Deconstruct(out int major, out int minor)
    {
        major = this.Major;
        minor = this.Minor;
    }

    public void Deconstruct(out int major, out int minor, out int patch)
    {
        major = this.Major;
        minor = this.Minor;
        patch = this.Patch;
    }
}

The .NET runtime uses these methods to deconstruct our Version into a tuple of two (or three) int, depending on how many values we want to deconstruct. Multiple overloads for the Deconstruct method can return a different number of out parameters.

Deconstruction builds on top of C# 7 tuples, which means the ValueTuple type is required. It’s built into .NET 4.7+, .NET Core 2.0, Mono 5.0 and .NET Standard 2.0 – for other target frameworks make sure to install the System.ValueTuple package. Note we also did a blog post around tuple support in ReSharper.

Generate deconstructor action and quick-fix

With ReSharper 2017.3 EAP, we’re adding better support for C# 7 deconstructors. The Generate action (Alt+Insert) now lets us generate a deconstructor based on fields and/or properties:
Generate deconstructor from fields and properties

ReSharper also comes with an inspection that verifies if a type contains a destructor. A quick-fix is also available that generates a Deconstruct method based on usage:
Inspection warns us about no suitable deconstructor available

Find usages

ReSharper 2017.3 also adds navigation support for deconstructors. For example, we can navigate to usages of a given deconstructor using the Navigate To (Alt+`) action, or directly using Find Usages (Shift+F12):
Solution-wide Find Usages for deconstructors

A nice thing about deconstruction is that it works for any type, including types from third party code! All we need is one or more Deconstruct method(s), either directly on our type or via an extension method. Here’s a nice example of how we can make consuming a dictionary in a foreach a bit nicer:

public static class KeyValuePairExtensions
{
    public static void Deconstruct<TKey, TValue>(
        this KeyValuePair<TKey, TValue> pair,
        out TKey key, out TValue value)
    {
        key = pair.Key;
        value = pair.Value;
    }
}

var dictionary = new Dictionary<string, string>();
foreach (var (key, value) in dictionary)
{
    // do something
}

For these extensions methods, we also get navigation assistance from ReSharper:
Find usages of deconstructor extension method

Download ReSharper 2017.3 EAP and give it a try! We’d love to hear your feedback!

image description