C#7: Throw Expressions and More Expression-bodied Members

In this installment of my look at C#7, we will take a look at some nice syntactical enhancements, including the first ever community contribution to the C# language implementation. Before we get started, here is a summary of what I am covering in this series on C#7.

Throw Expressions

We have all written code like this1:

public class MyApiType
{
    private object _loadedResource;
    private object _someProperty;

    public MyApiType()
    {
        _loadedResource = LoadResource();
        if (_loadedResource == null) throw new InvalidOperationException();
    }

    public object SomeProperty
    {
        get
        {
            return _someProperty;
        }
    
        set
        {
            if (value == null) throw new ArgumentNullException();
            _someProperty = value;
        }
    }
}

I have omitted the exception arguments for brevity, but you should hopefully recognise the sort of sanity checking to which I am referring within the highlighted lines.

With throw expressions, we can now combine assignment, the null-coalescing operator2, and throw to create succinct validation code. This means that the example above can be simplified to not even need the constructor.

public class MyApiType
{
    private object _loadedResource = LoadResource() ?? throw new InvalidOperationException();
    private object _someProperty;

    public object SomeProperty
    {
        get
        {
            return _someProperty;
        }
    
        set
        {
            _someProperty = value ?? throw new ArgumentNullException();
        }
    }
}

The highlighted lines are equivalent to the code we had earlier, but now we are able to use throw as part of the expression. The introduction of throw expressions means that we can now throw exceptions in conditional and null-coalescing expressions, as well as some lambda methods where it was previously not possible to do so. Not only that, but when combined with expression-bodied members, we can write some very expressive yet terse code.

Expression-bodied Members

With C#6 we got expression-bodied members, which allowed us to express simple methods using lambda-like syntax. However, this new syntax was limited to methods and read-only properties. Via the first ever community contribution to C#3, C#7 expands this syntax to cover constructors, finalizers, and property accessors.

If we take the property example we had before, containing our throw expression as part of  property set accessor, we can now write it as:

public object SomeProperty
{
    get => _someProperty;
    set => _someProperty = value ?? throw new ArgumentNullException();
}

I won't bother with examples for constructors or finalizers; the main documentation is pretty clear on those and I am not convinced the syntax will be used very often in those cases. Constructors are rarely so simple that the expression-bodied syntax makes sense, and finalizers are so rarely needed4 that most of us will not get an opportunity to write one at all, expression-bodied or otherwise.

In Conclusion

These simple additions to the C# syntax enable us to write terse code without losing clarity, which is always a good thing. Not only that, but we have reached a landmark event; community contributions to C#. This contribution may be a little tame when compared with some of the other features coming in C#7, but it bodes well for the future of the language in its new, open source home.

Next time, we will take a look at the highly anticipated pattern matching. Until then, feel free to leave a comment, or read more about C#7 on my blog and on the official documentation.

  1. Let's ignore the nastiness of throwing exceptions during construction []
  2. You remember Elvis, right?? []
  3. Source: https://docs.microsoft.com/en-us/dotnet/articles/csharp/csharp-7#more-expression-bodied-members []
  4. If you find yourself writing a finalizer, I recommend you make sure you really need it; there is probably a better way []