One of my favorite features that was added in C# 7 was support for multiple variable assignment from return values via the use of Tuples. Here’s a quick example of a function that declares multiple return values.

public (Article[] articles, string[] tags) FindArticles(DateTimeOffset begin, DateTimeOffset end)
{
    // query data ...
    return (articles, tags);
}

And calling it would then look like…

(var articles, var tags) = FindArticles(begin, end);

The alternatives to this prior to C# 7 would be either to declare a class to wrap the values into a single return type, to create out parameters, or else to make multiple function calls (e.g. FindArticles/FindTags…).

The new C# 7 syntax provides a nice clean symmetry between the return type declaration and the assignment statement. Under the hood, the C# compiler is using System.ValueTuple to represent the return values. If you’re targeting a .NET Framework version earlier that 4.7 or targeting NET Standard 1.x, then you’ll need to add a reference to the ValueTuple NuGet package.

As with most new language features, there are a few caveats to consider.

  • First, the multiple return values feature should not replace proper modelling or DTOs. Think of it more as a garnish to mix into your existing code to make certain calls (or combination of calls) more convenient. For example, it can eliminate some of the “throw away” types that are created simply for returning groups of objects together.
  • Currently, it is recommended that multiple return value use is kept internal to a library or application and that is not be used as part of its public interface. Consider a scenario where you would have to work with a library from an earlier version of C#, and having to deal with the ValueTuple directly is not so useful.
  • There is extra work needed to make C# 7 work with ASP.NET projects hosted on the .NET Framework (especially if you are upgrading an older existing project). You will need to make sure the ASP.NET CodeDom compiler NuGet package for ASP.NET is installed (a.k.a. Microsoft.CodeDom.Providers.DotNetCompilerPlatform), which will in turn bring in the Roslyn compiler NuGet package (Microsoft.Net.Compilers). Be careful here! If your target environment uses the 4.5.x runtime, then the highest compatible version of Microsoft.Net.Compilers is 1.3.2, which effectively limits you to C# 6. NuGet may automatically bring in the latest 2.x Roslyn compiler package, which will lead to compilation errors once you deploy your app to the 4.5.x running server (been there, got the T-shirt.)

Deconstructing to Multiple Variable Assignment

The formal term for the assignment of multiple discrete variables from a return value is called Deconstruction. While the syntax shown above utilizes tuples, C# 7 allows other types to be used for multiple assignment as well.  Deconstruction provides a compact syntax for assigning variables from values contained in an object. It also somewhat bridges the gap between allowing the new C# syntax to be used with a function while keeping that function backwards compatible with C# 6 and earlier consumers (see the final example in this post). Support for deconstructing an existing type can be added via a convention method named Deconstruct and giving the method one or more out parameters.

As an example, let’s wrap up the return values from the first example into a new type.

public class FindArticlesResult
{
    public Article[] Articles;
    public string[] Tags;

    public void Deconstruct(out Article[] articles, out string[] tags)
    {
        articles = Articles;
        tags = Tags;
    }
}

The FindArticles method is then updated as follows…

public FindArticlesResult FindArticles(DateTimeOffset begin, DateTimeOffset end)
{
    // query data ...
    return new FindArticlesResult()
    {
        Articles = articles,
        Tags = tags
    };
}

From C# 7 it can be called with the same syntax as before.

(var articles, var tags) = FindArticles(begin, end);

// NOTE: multiple assignment can be done from an existing variable as well.
var result = FindArticles(begin, end);
(var articles, var tags) = result;

From C# 6 and earlier, the result can be accessed directly.

var result = FindArticles(begin, end);
var articles = result.Articles;
var tags = result.Tags;

That’s all for now! Be sure to check out the great documentation on docs.microsoft.com that covers Tuples and Deconstruction in more detail.

Welcome to my new blog!

For quite a while now, I’ve bought into the opinions voiced by blogging celebrities such as Scott Hanselman and Troy Hunt. For example, Scott makes compelling arguments that more bloggers are needed to strengthen their respective communities, and also that you should also “own your words.” That is, don’t do all your writing in a walled garden owned by a giant social media company. That resonates with me. I also like the idea of using a blog as a tool for personal documentation and as a public log for sharing research with others, which is how I’ve heard Jon Skeet, another one of my favorite bloggers, describe his blog. Finally, I want to use my blog as a tool to simply help me focus on researching and documenting topics that interest me. However, there’s a big gap between wanting something intellectually and sitting down to put in the time to build it.

So, this is my first post - short and sweet. In the next post, I plan to dive straight into some technical content!