In this article, we are going to learn how expression body definitions and expression-bodied members in C# work.

Expression body definitions let us define our methods and properties using a simplified and concise syntax that is extremely readable. We can use expression body definitions if our method or property consists of a single expression.

C# 6 introduced expression body definitions for methods and read-only properties. C# 7.0 introduced property setters and getters, constructors, and finalizers.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!
To download the source code for this article, you can visit our GitHub repository.

Let’s get started.

Expression-bodied Methods

Let’s see an example of an expression-bodied method: 

public class Square
{
    private double _side;

    public Square(double side)
    {
        _side = side;
    }

    public double CalculateArea() => Math.Pow(_side, 2);
}

public class Program
{
    public static void Main(string[] args)
    {
        var square = new Square(2);

        Console.WriteLine($"Square area is {square.CalculateArea()}");
    }
}

Here we create a Square class that contains a method CalculateArea() defined using an expression body. Furthermore, we create an instance of the Square class inside the Main method. Finally,  we use the previously defined expression-bodied method to output the area of a square of side 2.

The expression body definition for a method must return a value whose type matches the method’s return type. If the return type defined in the method’s signature is void, any value returned by the expression will be lost.

Expression-bodied Properties

Expression bodies in read-only properties are very similar to methods. Let’s refactor our previous example so we have an Area property in the Square class instead of a CalculateArea() method. Let’s do it using an expression body:

public class Square
{
    private double _side;

    public Square(double side)
    {
        _side = side;
    }

    public double Area => Math.Pow(_side, 2);
}

Now we can access the area of the square via the new property:

Console.WriteLine($"Square area is {square.Area}");

Properties that have setters and getters can also benefit from the simplified syntax of expression bodies:

public class Employee
{
    private string _name;

    public string Name
    {
        get => _name;
        set => _name = value;
    }
}

So, we define an Employee class that exposes a public property Name backed by a private field. Both the setter and the getter for the Name property are implemented using expression body syntax.

Indexer objects can use expression bodies since, typically, their set and get accessors only consist of a single expression. Let’s see an example:

public class Staff
{
    private readonly string[] _staff = { "John", "Mary", "Derrick", "Paul", "Lisa" };

    public string this[int index]
    {
        get => _staff[index];
        set => _staff[index] = value;
    }
}

This example shows how we implement an indexer class Staff that contains a collection of employee names. We use expression body definitions to implement the get and set accessors for each individual element.

Expression-bodied Constructors and Finalizers

Since C# 7.0, expression bodies are available for constructors and finalizers. As with properties, this is possible only when the implementation consists only of a single expression or method call.

Let’s take a look at an example where we extend our previous Employee class with an expression-bodied constructor and a finalizer:

public class Employee
{
    private string _name;

    public string Name
    {
        get => _name;
        set => _name = value;
    }

    public Employee(string name) => _name = name;

    ~Employee() => Console.WriteLine("Employee object has been finalized");
}

In this example, after the private field _name and the public property Name, we define a constructor that takes a parameter called name of type string and initializes the private field with its value. After that, we implement a finalizer method that will output a message to the console when the garbage collector finalizes the object instance.

Limitations of Expression-bodied Members in C#

Expression body definitions, unlike general lambda expressions, do not support code blocks. They only allow a single expression without curly braces or return statements. That means that we can’t use if statements in an expression-bodied member. However, we can use the ternary operator:

public string Position => _employer != null ? $"{_position} at {_employer}" : "Unemployed";

The fact that code blocks are not supported in expression body definitions also prevents us from using loops. Probably, if your class member needs a loop, your best option is to just use regular method definition syntax. However, if you really need to define it as an expression-bodied member you might be able to use LINQ queries instead.

Conclusion

We’ve learned how expression body definitions let you define your methods and properties using a simplified syntax. This syntax is available for general methods, read-only properties, setters and getters, indexer objects, constructors, and finalizers. 

To wrap things up, we’ve learned how expression body definitions always consist of a single expression and do not support code blocks.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!