Expression Bodied Members (C# 6)

C# 6

Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

Expression bodied members are a new feature in C# 6 and are a very interesting feature that aims to reduce the number of lines of code in your app for simple tasks. What do I mean by "simple tasks"? Anything that consists of a single statement.

I use the word statement and not line because you can break a statement across multiple lines and it will still work. Think of a statement as complete when you hit the first semicolon (;).

Here are some examples of one-statement code blocks:

// a method with one statement in it
private double Tax()
{
    return 1.14;
}

// a read-only property with one statement
public double Price
{
    get
    {
        return CostPrice * Tax();
    }
}

// a method calling an event, in this case using the [null-propagation operator](/content/null-propagation-operator-nullet-c-6)
private void RaisePain(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

All examples contain a single statement but span multiple lines. The first and last examples are 4 lines of code (4:1 ratio), and the second example is 7 lines of code (7:1 ratio). Expression bodied members aim to reduce this to a 1:1 ratio! 😊

Expression Bodied Members

The name of this feature hints at everything you need to know: it applies to members (properties, methods, etc.), it’s an expression, and we use the => operator followed by the body of that expression. Applying this logic to the first example, we can rewrite them as follows:

// still a method, but now one line
private double Tax() => 1.14;

// still a read-only property
public double Price => CostPrice * Tax();

// still a method
private void RaisePain(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

This dramatically cuts the code-to-statement ratio and lets you express simple tasks without much ceremony.

While it uses the => operator, I’ve intentionally avoided calling these lambdas because they don’t support all lambda functionality.

Supported and Unsupported Scenarios

As we’ve seen, both methods (with or without parameters) and read-only properties (those without a setter) are supported. Operators are also supported:

public static Complex operator +(Complex a, Complex b) => a.Add(b);

Converters (implicit or explicit) are also supported:

public static implicit operator string(Name n) => n.First + " " + n.Last;

Indexers are also supported:

public Customer this[Id id] => store.LookupCustomer(id);

However, some members aren’t supported by this feature:

In summary, I think this feature should help create cleaner and simpler code—but what do you think?