Skip to main content

C# Expression-bodied Methods

Introduction

Expression-bodied methods are a concise way to define methods in C# that consist of a single expression. Introduced in C# 6.0 and expanded in later versions, they provide a more elegant syntax for simple method implementations, making your code more readable and maintainable.

In this tutorial, we'll cover how expression-bodied methods work, when to use them, and see practical examples that demonstrate their benefits.

What Are Expression-bodied Methods?

Expression-bodied methods are a syntactic shorthand that allows you to replace the traditional method body (enclosed in curly braces) with a => operator followed by a single expression. The result of this expression is automatically returned from the method.

Traditional Method vs. Expression-bodied Method

Here's a comparison of traditional method syntax and expression-bodied syntax:

csharp
// Traditional method
public int Add(int a, int b)
{
return a + b;
}

// Expression-bodied method
public int Add(int a, int b) => a + b;

As you can see, the expression-bodied method is more concise and eliminates the need for the return keyword and curly braces.

Basic Syntax and Usage

The basic syntax for an expression-bodied method is:

csharp
access_modifier return_type MethodName(parameters) => expression;

Let's look at different types of methods that can benefit from this syntax:

Instance Methods

csharp
public class Calculator
{
// Expression-bodied instance method
public int Add(int a, int b) => a + b;

public double CalculateArea(double radius) => Math.PI * radius * radius;
}

Static Methods

csharp
public class MathHelper
{
// Expression-bodied static method
public static int Square(int number) => number * number;

public static bool IsEven(int number) => number % 2 == 0;
}

Using Expression-bodied Methods with Different Return Types

Expression-bodied methods work with all return types:

Void Methods (C# 7.0+)

Starting with C# 7.0, you can use expression-bodied syntax for methods that don't return a value:

csharp
public class Logger
{
// Expression-bodied void method
public void LogMessage(string message) => Console.WriteLine($"LOG: {message}");
}

Methods Returning Complex Types

csharp
public class PersonFactory
{
public Person CreatePerson(string name, int age) => new Person { Name = name, Age = age };
}

Methods Returning Collections

csharp
public class NumberGenerator
{
public List<int> GetEvenNumbers(int count) =>
Enumerable.Range(1, count * 2).Where(n => n % 2 == 0).ToList();
}

Practical Examples

Let's explore some practical scenarios where expression-bodied methods are particularly useful:

Example 1: Data Transformation

csharp
public class UserService
{
public UserViewModel MapToViewModel(User user) =>
new UserViewModel
{
DisplayName = $"{user.FirstName} {user.LastName}",
Email = user.Email,
MemberSince = user.JoinDate.ToString("MMM yyyy")
};
}

Example 2: Validation Methods

csharp
public class InputValidator
{
public bool IsValidEmail(string email) =>
!string.IsNullOrEmpty(email) && email.Contains("@") && email.Contains(".");

public bool IsAdult(DateTime birthDate) =>
(DateTime.Now - birthDate).TotalDays > 365 * 18;
}

Example 3: LINQ-based Operations

csharp
public class ProductService
{
private List<Product> _products;

// Find products by category
public IEnumerable<Product> FindByCategory(string category) =>
_products.Where(p => p.Category == category);

// Get the average price
public decimal GetAveragePrice() => _products.Average(p => p.Price);
}

Complete Program Example

Let's see a complete program that demonstrates expression-bodied methods in action:

csharp
using System;
using System.Collections.Generic;
using System.Linq;

namespace ExpressionBodiedMethodsDemo
{
class Program
{
static void Main(string[] args)
{
// Create a text processor and use its methods
var processor = new TextProcessor();

string sampleText = "Hello, expression-bodied methods!";

Console.WriteLine($"Original text: {sampleText}");
Console.WriteLine($"Word count: {processor.CountWords(sampleText)}");
Console.WriteLine($"Character count: {processor.CountCharacters(sampleText)}");
Console.WriteLine($"Uppercase: {processor.ToUpperCase(sampleText)}");
Console.WriteLine($"Reversed: {processor.Reverse(sampleText)}");

// Use statistics calculator
var numbers = new List<int> { 5, 2, 8, 9, 1, 7, 3, 6, 4 };
var stats = new StatisticsCalculator();

Console.WriteLine($"\nNumbers: {string.Join(", ", numbers)}");
Console.WriteLine($"Average: {stats.Average(numbers)}");
Console.WriteLine($"Minimum: {stats.Min(numbers)}");
Console.WriteLine($"Maximum: {stats.Max(numbers)}");
Console.WriteLine($"Sum: {stats.Sum(numbers)}");
Console.WriteLine($"Even numbers: {string.Join(", ", stats.GetEvenNumbers(numbers))}");
}
}

class TextProcessor
{
// All methods using expression-bodied syntax
public int CountWords(string text) =>
string.IsNullOrWhiteSpace(text) ? 0 : text.Split(new[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries).Length;

public int CountCharacters(string text) => text?.Length ?? 0;

public string ToUpperCase(string text) => text?.ToUpper();

public string Reverse(string text) =>
new string(text?.Reverse().ToArray() ?? Array.Empty<char>());
}

class StatisticsCalculator
{
// Calculate average of numbers
public double Average(List<int> numbers) => numbers.Any() ? numbers.Average() : 0;

// Get minimum value
public int Min(List<int> numbers) => numbers.Any() ? numbers.Min() : 0;

// Get maximum value
public int Max(List<int> numbers) => numbers.Any() ? numbers.Max() : 0;

// Calculate sum
public int Sum(List<int> numbers) => numbers.Sum();

// Get even numbers
public IEnumerable<int> GetEvenNumbers(List<int> numbers) =>
numbers.Where(n => n % 2 == 0);
}
}

Output:

Original text: Hello, expression-bodied methods!
Word count: 3
Character count: 32
Uppercase: HELLO, EXPRESSION-BODIED METHODS!
Reversed: !sdohtem deIdob-noisserpxe ,olleH

Numbers: 5, 2, 8, 9, 1, 7, 3, 6, 4
Average: 5
Minimum: 1
Maximum: 9
Sum: 45
Even numbers: 2, 8, 6, 4

Best Practices for Using Expression-bodied Methods

  1. Keep it simple: Use expression-bodied methods for simple, one-line operations. If the logic becomes complex, use a traditional method body.

  2. Readability matters: Only use expression-bodied methods when they improve readability. Sometimes a traditional method body is clearer, especially for beginners.

  3. Ideal use cases:

    • Simple calculations
    • Property transformations
    • Short LINQ queries
    • Delegate implementations
    • Condition checks
  4. Avoid for complex logic: Don't use them for methods that contain multiple operations or complex logic.

When Not to Use Expression-bodied Methods

While expression-bodied methods are concise, they're not always the best choice:

csharp
// Not ideal for expression-bodied method - too complex
public List<Product> GetDiscountedProducts(List<Product> products, decimal discountPercentage) =>
products.Select(p => {
p.Price = p.Price * (1 - discountPercentage / 100);
p.IsOnSale = true;
p.LastUpdated = DateTime.Now;
return p;
}).ToList();

// Better as a traditional method
public List<Product> GetDiscountedProducts(List<Product> products, decimal discountPercentage)
{
var result = new List<Product>();

foreach (var product in products)
{
product.Price = product.Price * (1 - discountPercentage / 100);
product.IsOnSale = true;
product.LastUpdated = DateTime.Now;
result.Add(product);
}

return result;
}

Summary

Expression-bodied methods provide a concise syntax for defining simple methods in C#. They are particularly useful for:

  • Methods that return a single expression
  • Simple calculations and transformations
  • Methods that delegate to other methods
  • Short LINQ queries and operations

Benefits include:

  • More concise code
  • Improved readability for simple operations
  • Less boilerplate for straightforward methods

Remember that the goal is to make your code more readable, not just shorter. Use expression-bodied methods when they enhance clarity, but don't hesitate to use traditional method bodies for more complex operations.

Additional Resources

Exercises

  1. Convert the following traditional methods to expression-bodied methods:

    csharp
    public int Multiply(int a, int b) { return a * b; }
    public string GetFullName(string first, string last) { return $"{first} {last}"; }
    public bool IsPositive(int number) { return number > 0; }
  2. Create a Circle class with expression-bodied methods to calculate area, circumference, and diameter.

  3. Write a StringHelper class with expression-bodied methods for common string operations (counting vowels, reversing words, checking palindromes, etc.).

  4. Implement a simple calculator using expression-bodied methods for basic arithmetic operations.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)