Expression-Bodied Members in C# Explained

Expression-bodied members in C# provide a clean and concise syntax for defining members whose implementations consist of a single expression. By using the lambda arrow operator (=>), developers can eliminate boilerplate code such as braces and return statements for methods, properties, and other class members. This article explains how expression-bodied members work, compares them to traditional block-bodied syntax, and demonstrates their usage in C# methods and properties.

Understanding Expression-Bodied Syntax

In standard C# code, methods and properties are defined using block bodies enclosed by curly braces {}. When an implementation contains only one executable statement or expression, this traditional syntax can introduce unnecessary visual clutter. Expression-bodied members resolve this by replacing the block body and explicit return keywords with the fat arrow operator (=>).

Introduced in C# 6.0 and expanded in C# 7.0, this feature is purely syntactic sugar; the C# compiler generates the exact same Intermediate Language (IL) as it does for standard block-bodied implementations.

Expression-Bodied Methods

An expression-bodied method consists of a single expression that either evaluates to the return type or executes a single void operation.

Methods Returning a Value

Instead of declaring a body block and writing a return statement, place the arrow operator directly after the parameter list.

Traditional Block Body:

public int Add(int a, int b)
{
    return a + b;
}

Expression-Bodied Syntax:

public int Add(int a, int b) => a + b;

Void Methods

Expression-bodied syntax also works with void methods, provided the operation is a valid statement expression, such as a method call or an assignment.

Traditional Block Body:

public void LogMessage(string message)
{
    Console.WriteLine($"[LOG]: {message}");
}

Expression-Bodied Syntax:

public void LogMessage(string message) => Console.WriteLine($"[LOG]: {message}");

Expression-Bodied Properties

Properties are one of the most common areas where expression-bodied members improve readability, especially for read-only calculated properties.

Read-Only Properties

When a property only contains a get accessor that returns a single expression, the get keyword and the outer braces can be omitted entirely.

Traditional Block Body:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName
    {
        get
        {
            return $"{FirstName} {LastName}";
        }
    }
}

Expression-Bodied Syntax:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}

In this form, FullName is a read-only property evaluated each time it is accessed.

Read/Write Properties

Starting in C# 7.0, individual get and set accessors inside a full property can be written as expression-bodied members.

Traditional Block Body:

private string _username;

public string Username
{
    get
    {
        return _username;
    }
    set
    {
        _username = value.Trim();
    }
}

Expression-Bodied Syntax:

private string _username;

public string Username
{
    get => _username;
    set => _username = value.Trim();
}

Key Considerations

  • Single Expression Limit: An expression-bodied member must contain exactly one expression. If the logic requires multiple statements, loops, or complex branching, a standard block body must be used.
  • Evaluation vs. Storage: An expression-bodied property like public DateTime Now => DateTime.Now; calculates the value on every access; it does not store the value like an auto-property initializer (public DateTime Now { get; } = DateTime.Now;).
  • Readability: Expression-bodied members are best suited for simple, one-line operations. Overly complex single expressions can harm readability and should be converted back to standard block bodies.