Quantcast
Channel: Don't Code Tired
Viewing all articles
Browse latest Browse all 207

Adding Tuple Support to .NET Classes in C#

$
0
0

Tuples in C# are objects that can be created with a specific syntax. You don’t have to declare tuple types first like you do with classes for example, they can instead be created using a lightweight C# syntax.

A tuple is a object that holds a number of arbitrary data items and which has no custom behaviour. In contrast, a class or struct can have both data and custom behaviour.

For example the following creates a tuple with 2 string values:

(string, string) names = ("Sarah", "Smith");
Console.WriteLine($"First name: '{names.Item1}' Last name: '{names.Item2}'");

This code produces the output: First name: 'Sarah' Last name: 'Smith'

In the preceding code, the items inside the tuple don’t have names so they are referred to as Item1 and Item2 but you could also name the items, for example:

(string firstName, string lastName) names = ("Sarah", "Smith");
Console.WriteLine($"First name: '{names.firstName}' Last name: '{names.lastName}'");

If you had a rich Person class that had both data and behaviour you could also add support for deconstructing  a Person instance into tuple elements.

Consider the following class:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int AgeInYears { get; set; }
    public string FavoriteColor { get; set; }
    // methods etc.
}

We could create a tuple as before containing the first and last name as follows:

var sarah = new Person
{
    FirstName = "Sarah",
    LastName = "Smith",
    AgeInYears = 42,
    FavoriteColor = "red"
};

(string firstName, string lastName) names = (sarah.FirstName, sarah.LastName);
Console.WriteLine($"First name: '{names.firstName}' Last name: '{names.lastName}'");

This is however a little clunky, we can modify the Person class to provide support for a Person to be deconstructed into tuple elements. To do this a public void method called Deconstruct can be added, for example:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int AgeInYears { get; set; }
    public string FavoriteColor { get; set; }

    // methods etc.

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

Now the code could be changed to:

var (firstName, lastName) = sarah;
Console.WriteLine($"First name: '{firstName}' Last name: '{lastName}'");

You could also add this deconstruction support to a class you can’t change by declaring an extension method such as:

static class PersonExtensions
{
    public static void Deconstruct(this Person person, out string firstName, out string lastName)
    {
        firstName = person.FirstName;
        lastName = person.LastName;
    }
}

Or as another example, you could add support for deconstruction to the .NET String type:

static class StringExtensions
{
    public static void Deconstruct(this string s, out string original, out string upper, out string lower, out int length)
    {
        original = s;
        upper = s.ToUpperInvariant();
        lower = s.ToLowerInvariant();
        length = s.Length;
    }
}

And then write:

var (original, upper, lower, length) = "The quick brown fox";
Console.WriteLine($"Original: {original}");
Console.WriteLine($"Uppercase: {upper}");
Console.WriteLine($"Lowercase: {lower}");
Console.WriteLine($"Length: {length}");

If you want to learn a load more C# tips check out my C# Tips and Traps course today. You can even currently start watching with a Pluralsight Free Trial with Unlimited Access.


Viewing all articles
Browse latest Browse all 207

Trending Articles