C# 7.0 – Deconstruction   Recently updated !


Facebooktwittergoogle_pluslinkedinmail

Deconstruction is a nice way to consume tuples. It’s a syntax that allows splitting a tuple into variables.

Note: You can view all code examples on GitHub. My environment: Visual Studio 2017 (15.7.5) and .NET Framework 4.6.1.

using System;

namespace CSharp7.Deconstruction
{
    class Example1
    {
        // Let's consider following method
        // Note: For tuple support you need to add System.ValueTuple NuGet
        (string name, int age) GetPerson() => ("John", 24);

        public void Run()
        {
            // Instead of assigning tuple and then use its variables:
            var personTuple = GetPerson();
            Console.WriteLine($"{personTuple.name} is {personTuple.age}");

            // It's fine to assign tuple's values directly - deconstruction
            (string name, int age) = GetPerson();
            Console.WriteLine($"{name} is {age}");
        }
    }
}

It’s also allowed to use var keyword for tuple deconstruction.

using System;

namespace CSharp7.Deconstruction
{
    class Example2
    {
        (string name, int age) GetPerson() => ("John", 24);

        public void Run()
        {
            (var name1, var age1) = GetPerson();
            Console.WriteLine($"{name1} is {age1}");

            var (name2, age2) = GetPerson();
            Console.WriteLine($"{name2} is {age2}");
        }
    }
}

Or even assign to previously defined variables.

namespace CSharp7.Deconstruction
{
    class Example3
    {
        (string name, int age) GetPerson() => ("John", 24);

        public void Run()
        {
            string name;
            int age;
            (name, age) = GetPerson();
        }
    }
}

 

Deconstruction is not limited only to tuples

Deconstruction is also available to any type. To support it, a type has to implement Deconstruct method with only out parameters.

using System;

namespace CSharp7.Deconstruction
{
    class Officer
    {
        public string Name { get; set; }
        public string Rank { get; set; }

        public void Deconstruct(out string name, out string rank)
        {
            name = Name;
            rank = Rank;
        }
    }

    class OfficerExample
    {
        Officer GetOfficer() =>
            new Officer
            {
                Name = "James Bond",
                Rank = "Commander"
            };

        public void Run()
        {
            // It's allowed to deconstruct an Officer instance
            Officer officer = GetOfficer();
            var (name1, rank1) = officer;
            Console.WriteLine($"{name1} is {rank1}");

            // Or just deconstruct directly result of a method
            var (name2, rank2) = GetOfficer();
            Console.WriteLine($"{name2} is {rank2}");
        }
    }
}

It’s also possible to add deconstruction support by an extension method.

using System;

namespace CSharp7.Deconstruction
{
    public class Car
    {
        public string Model { get; set; }
        public string Owner { get; set; }
    }

    public static class CarExtensions
    {
        public static void Deconstruct(this Car car, out string model, out string owner)
        {
            model = car.Model;
            owner = car.Owner;
        }
    }

    class CarExample
    {
        Car GetCar() => new Car { Model = "Tesla", Owner = "Elon" };

        public void Run()
        {
            // Then we can deconstruct the car
            var (model, owner) = GetCar();
            Console.WriteLine($"{model} belongs to {owner}");
        }
    }
}

 

Facebooktwittergoogle_pluslinkedinmail

Leave a comment

Your email address will not be published. Required fields are marked *