DEV Community

Mark Clearwater
Mark Clearwater

Posted on • Originally published at blog.csmac.nz on

Looking Back on C# 7: Out variables

Looking Back on C# 7: Out variables

With C# 8 on our doorstep, I figure it is a good time to reflect on recent additions to the language that have come before. There are some great improvements you may have missed, some that I really enjoy using, and some I consider have reached canonical usage status that I think are all worth some reflection.

What are out parameters?

Sometimes you want a method to pass back a value by reference. In C and C++ this is done by passing the address in as an argument. In C#, we use the out keyword.

public bool HasCount(string str, out int length)
{
    length = 0;
    if (str.Length > 0)
    {
        length = str.Length;
        return true;
    }
}

string myString = "A String";
int length;
if (HasCount(myString, out length))
{
    // Do some stuff here.
}

A method must initialise the out parameter value, but the caller doesn't have to initialise it first. Callers must use the out keyword when calling a method with an out parameter. This helps with readability making it unambiguous how it works.

More details of this for those unfamiliar with the concept can be found here.

In the libraries, there are a few methods that use this, for instance Int32.TryParse.

int number;
if (Int32.TryParse(numberAsString, out number))
{
    // use `number` as an integer value. 
}

It also comes in useful when you are building C-style interops. But not something you see very much these days.

New out variables

This syntax always felt a bit clunky. Modern APIs would suggest using a return value over an out parameter, and the early use cases tended to be either cross-compatibility with C libraries or parse scenarios. Primarily it was discouraged for readability reasons, though there are benefits from using it in certain places.

However, with C# 7, a new syntax was introduced, allowing inline declaration of out parameters.

if (Int32.TryParse(numberAsString, out int number))
{
    // use `number` as an integer value. 
}

You can now declare the parameter inline, without needing the empty declaration line that was essentially wasting line-count. The other benefit is you can now use var instead of an explicit type.

if (Int32.TryParse(numberAsString, out var number))
{
    // use `number` as an integer value. 
}

In C# 7.3, this out variable syntax was extended to include field initializers, property initializers, constructor initializers, and query clauses. Basically, you have the power to use this everywhere that you can use out parameters.

With the new changes, readability has hugely increased, the risk of using the value before initialisation has been removed, and it is probably something worth encouraging using again in those methods that could benefit with having out parameters for clean APIs, and performance.

A small but simple improvement to the language that I would replace in every place you use out parameters.

Top comments (0)