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.