← Back to Articles         
Delegates – Lambda Expressions vs Anonymous Methods

Delegates – Lambda Expressions vs Anonymous Methods

Published on 12 Oct 2026     12 min read C#
Delegates, Events & Lambda Expressions
 

C# Delegates – Lambda Expressions vs Anonymous Methods

Both lambda expressions and anonymous methods allow us to write methods without explicitly declaring a method name.

They are commonly used with delegates, LINQ, callbacks, and event handling.

1. What is a Lambda Expression in C#?

Definition

A lambda expression is a concise way to define an anonymous function using the lambda operator (=>).

It allows us to write a function directly where it is needed, without creating a separate named method.

Lambda expressions are commonly used with:

  • Func, Action, and Predicate delegates.

  • LINQ queries such as Where(), Select(), and OrderBy().

  • Event handlers and callbacks.

  • Expression trees.

  • Filtering, sorting, and transforming collections.

Syntax

(parameters) => expression

Or, for multiple statements:

(parameters) =>
{
    // Statements
    return result;
};

The => operator is called the lambda operator and is commonly read as goes to.

Example 1 – Normal Method vs Lambda Expression

First, consider a normal C# method.

using System;

class Program
{
    static int Add(int a, int b)
    {
        return a + b;
    }

    static void Main()
    {
        int result = Add(10, 20);

        Console.WriteLine(result);
    }
}

Output:

30

Now, write the same logic using a lambda expression.

using System;

class Program
{
    static void Main()
    {
        Func<int, int, int> add = (a, b) => a + b;

        int result = add(10, 20);

        Console.WriteLine(result);
    }
}

Output:

30

Step-by-Step Explanation

Step 1: Declare a Func delegate.

Func<int, int, int> add;
  • First int – First input parameter.

  • Second int – Second input parameter.

  • Third int – Return type.

Step 2: Assign a lambda expression.

add = (a, b) => a + b;

Here:

  • (a, b) represents the input parameters.

  • => separates the parameters from the function body.

  • a + b is the expression that produces the return value.

Step 3: Execute the delegate.

int result = add(10, 20);

The lambda expression calculates 10 + 20 and returns 30.

Execution Flow

Func<int, int, int> add = (a, b) => a + b
                         |
                         v
                   Lambda Expression
                         |
                         v
                    add(10, 20)
                         |
                         v
                     a = 10
                     b = 20
                         |
                         v
                      a + b
                         |
                         v
                    Returns 30
 

2. Types of Lambda Expressions

C# supports two primary forms of lambda expressions.

A. Expression Lambda

An expression lambda contains a single expression.

Syntax:

(parameters) => expression

Example:

Func<int, int> square = x => x * x;

Console.WriteLine(square(5));

Output:

25

Explanation:

The lambda accepts an integer and returns its square.

An explicit return statement is not required because the expression produces the result.

B. Statement Lambda

A statement lambda contains a block of statements enclosed in { }.

Syntax:

(parameters) =>
{
    // Multiple statements
    return result;
};

Example:

Func<int, int, int> calculate = (a, b) =>
{
    int sum = a + b;

    int result = sum * 2;

    return result;
};

Console.WriteLine(calculate(10, 20));

Output:

60

Explanation:

  1. a = 10, b = 20.

  2. Calculate sum = 30.

  3. Multiply the sum by 2.

  4. Return 60.

Expression Lambda vs Statement Lambda

Feature

Expression Lambda

Statement Lambda

Syntax

(x) => x * 2

(x) => { return x * 2; }

Body

Single expression

Statement block

Explicit return

Not needed

Required when returning a value on that path

Multiple statements

No

Yes

Expression tree conversion

Supported for compatible expressions

Not supported directly

Best use

Simple calculations and conditions

More complex logic

 

3. Lambda Expressions with Func, Action, and Predicate

Lambda expressions are commonly assigned to built-in delegates.

Complete Example Program

using System;

class Program
{
    static void Main()
    {
        // Func - Returns a value
        Func<int, int, int> add = (a, b) => a + b;

        // Action - Returns void
        Action<string> display = message =>
        {
            Console.WriteLine(message);
        };

        // Predicate - Returns bool
        Predicate<int> isEven = number =>
        {
            return number % 2 == 0;
        };

        int result = add(10, 20);

        display($"Addition: {result}");

        Console.WriteLine($"Is Even: {isEven(result)}");
    }
}

Output

Addition: 30
Is Even: True

Explanation

  • Func executes the lambda and returns the sum.

  • Action executes the lambda to display a message without returning a value.

  • Predicate executes the lambda to check whether a number is even.

Important: A lambda expression is not itself a delegate type. It is a function expression that can be converted to a compatible delegate type or, when supported, an expression tree.

 

4. Real-World Example – Lambda Expressions with LINQ

Lambda expressions are extensively used in LINQ.

Consider a collection of employees.

Example Program

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

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public decimal Salary { get; set; }
}

class Program
{
    static void Main()
    {
        List<Employee> employees = new()
        {
            new Employee { Id = 1, Name = "John", Salary = 30000 },
            new Employee { Id = 2, Name = "David", Salary = 60000 },
            new Employee { Id = 3, Name = "Peter", Salary = 45000 },
            new Employee { Id = 4, Name = "James", Salary = 70000 }
        };

        var result = employees
            .Where(e => e.Salary > 50000)
            .OrderBy(e => e.Name)
            .ToList();

        foreach (var employee in result)
        {
            Console.WriteLine(
                $"{employee.Name} - {employee.Salary}");
        }
    }
}

Output

David - 60000
James - 70000

Step-by-Step Explanation

Step 1: Filter employees based on salary.

.Where(e => e.Salary > 50000)

The lambda accepts an employee and checks whether the salary is greater than 50,000.

Step 2: Sort the filtered employees.

.OrderBy(e => e.Name)

The lambda returns each employee's name, which LINQ uses as the sorting key.

Step 3: Convert the result into a list.

.ToList();

Step 4: Display the matching employees.

Execution Flow

Employee Collection
        |
        v
Where(e => e.Salary > 50000)
        |
        +-- John  : 30000 -> Excluded
        |
        +-- David : 60000 -> Included
        |
        +-- Peter : 45000 -> Excluded
        |
        +-- James : 70000 -> Included
        |
        v
OrderBy(e => e.Name)
        |
        v
David
James
        |
        v
ToList()
        |
        v
Display Results

Key Points – Lambda Expressions

  1. A lambda expression defines an anonymous function using =>.

  2. It reduces the need to declare separate named methods for short operations.

  3. It can be assigned to compatible delegates such as Func, Action, and Predicate.

  4. It supports both expression bodies and statement bodies.

  5. It is widely used in LINQ, callbacks, and event handling.

  6. Lambda expressions can capture variables from their enclosing scope. This is known as a closure.

  7. Compatible expression lambdas can be converted into expression trees using Expression<TDelegate>.

  8. In EF Core, expression trees allow LINQ expressions to be inspected and translated into SQL.

 

5. What is an Anonymous Method in C#?

Definition

An anonymous method is a method without an explicitly declared name, defined using the delegate keyword.

It allows us to define a block of executable code directly and assign it to a compatible delegate.

Anonymous methods were introduced in C# 2.0, while lambda expressions were introduced in C# 3.0.

Syntax

delegate (parameters)
{
    // Statements
};

Example Program

using System;

class Program
{
    static void Main()
    {
        Func<int, int, int> add = delegate(int a, int b)
        {
            return a + b;
        };

        int result = add(10, 20);

        Console.WriteLine(result);
    }
}

Output

30

Step-by-Step Explanation

Step 1: Declare a delegate variable.

Func<int, int, int> add;

Step 2: Assign an anonymous method.

add = delegate(int a, int b)
{
    return a + b;
};

The delegate keyword defines the anonymous method.

Step 3: Invoke the delegate.

int result = add(10, 20);

The anonymous method executes and returns 30.

Execution Flow

Func<int, int, int> add
         |
         v
delegate(int a, int b)
{
    return a + b;
}
         |
         v
     add(10, 20)
         |
         v
     a = 10
     b = 20
         |
         v
     Returns 30
 

6. Anonymous Method vs Lambda Expression – Same Example

Let's implement the same addition operation in three different ways.

A. Named Method

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

Func<int, int, int> calculate = Add;

B. Anonymous Method

Func<int, int, int> calculate = delegate(int a, int b)
{
    return a + b;
};

C. Lambda Expression

Func<int, int, int> calculate = (a, b) => a + b;

All three can be invoked using:

Console.WriteLine(calculate(10, 20));

Output:

30

Comparison Diagram

                 C# Function Definitions
                          |
           +--------------+--------------+
           |              |              |
           v              v              v
      Named Method   Anonymous Method   Lambda
           |              |              |
           v              v              v
      Add(a, b)      delegate(a,b)     (a,b) =>
           |              |              |
           +--------------+--------------+
                          |
                          v
                  Execute Addition
                          |
                          v
                     Return 30
 

7. Difference Between Anonymous Methods and Lambda Expressions

Feature

Anonymous Method

Lambda Expression

Introduced

C# 2.0

C# 3.0

Keyword/operator

delegate

=>

Syntax

More verbose

More concise

Method name

Not required

Not required

Parameters

Explicit types or omitted parameter list

Explicit or inferred types

Expression body

No

Yes

Statement body

Yes

Yes

Delegate support

Yes

Yes

Expression tree support

No direct conversion

Yes, for compatible expression lambdas

LINQ usage

Possible with delegate-based APIs

Preferred and widely used

Closures

Supported

Supported

Modern C# preference

Less common

Generally preferred

Important Difference – Expression Trees

One major technical difference is that compatible lambda expressions can be converted into expression trees, whereas anonymous methods cannot.

Lambda expression:

using System;
using System.Linq.Expressions;

Expression<Func<int, bool>> isAdult = age => age >= 18;

This is valid.

Anonymous method:

Expression<Func<int, bool>> isAdult =
    delegate(int age)
    {
        return age >= 18;
    };

This produces a compilation error because an anonymous method cannot be converted to an expression tree.

Why Is This Important in EF Core?

Consider:

var employees = dbContext.Employees
    .Where(e => e.Salary > 50000)
    .ToList();

Here, dbContext.Employees is normally an IQueryable<Employee>.

The Where() call uses an expression tree representing:

e => e.Salary > 50000

EF Core can analyze this expression and translate it into SQL.

Conceptually:

SELECT *
FROM Employees
WHERE Salary > 50000;

The expression tree is important because EF Core needs to understand the structure of the condition, not merely execute a compiled delegate in memory.

 

8. Important Concept – Closures in Lambda Expressions and Anonymous Methods

Both lambda expressions and anonymous methods can access variables declared in their enclosing scope.

This is called a closure.

Example Program

using System;

class Program
{
    static void Main()
    {
        int bonus = 5000;

        Func<int, int> calculateSalary =
            salary => salary + bonus;

        Console.WriteLine(calculateSalary(30000));

        bonus = 10000;

        Console.WriteLine(calculateSalary(30000));
    }
}

Output

35000
40000

Explanation

The lambda expression captures the local variable bonus.

When bonus changes from 5000 to 10000, the lambda observes the updated value.

It does not automatically preserve a snapshot of the original value.

Execution Flow

bonus = 5000
      |
      v
Create Lambda
      |
      v
calculateSalary(30000)
      |
      v
30000 + 5000 = 35000
      |
      v
bonus = 10000
      |
      v
calculateSalary(30000)
      |
      v
30000 + 10000 = 40000

The equivalent anonymous method is:

int bonus = 5000;

Func<int, int> calculateSalary = delegate(int salary)
{
    return salary + bonus;
};

This also captures bonus.

Important: Captured variables may have their lifetimes extended by the compiler-generated closure. In long-lived callbacks or event handlers, this can affect memory usage and object lifetime.

 

9. Important Interview Questions

Q1. Are lambda expressions and anonymous methods the same?

They are related but not identical.

Both define anonymous functions and can be assigned to compatible delegates. However, lambda expressions provide more concise syntax and support expression tree conversion for compatible expression-bodied lambdas.

Q2. Can lambda expressions contain multiple statements?

Yes.

Func<int, int> calculate = x =>
{
    int result = x * 2;
    return result + 10;
};

Q3. Can anonymous methods return values?

Yes, provided their delegate signature supports a return value.

Func<int, int> square = delegate(int x)
{
    return x * x;
};

Q4. Can lambda expressions access local variables?

Yes. Lambda expressions can capture local variables from their enclosing scope.

This mechanism is called a closure.

Q5. Can anonymous methods be used with LINQ?

Yes, when the LINQ API expects a compatible delegate.

For example:

List<int> numbers = new() { 10, 15, 20, 25 };

var result = numbers
    .Where(delegate(int x) { return x > 15; })
    .ToList();

This works because Enumerable.Where() accepts Func<T, bool>.

However, anonymous methods cannot directly replace expression trees in Queryable.Where().

Q6. Which should we use in modern C# applications?

Lambda expressions are generally preferred because they are concise, readable, and work naturally with LINQ.

Named methods remain useful when logic is complex, reused extensively, or benefits from a descriptive method name.

 

10. Final Key Points for Interviews

  1. Lambda expressions use the => operator.

  2. Anonymous methods use the delegate keyword.

  3. Both allow anonymous functions without explicitly declaring a named method.

  4. Both can be assigned to compatible delegates.

  5. Lambda expressions support expression and statement bodies.

  6. Anonymous methods use statement blocks.

  7. Both can capture variables from their enclosing scope.

  8. Compatible expression lambdas support expression tree conversion.

  9. Anonymous methods cannot be directly converted into expression trees.

  10. Lambda expressions are generally preferred in modern C#, particularly with LINQ and EF Core.

11. Interview-Ready Answers

Q1. What is a lambda expression?

A lambda expression is a concise way to define an anonymous function using the => operator. It can accept parameters, execute logic, and return a value. Lambda expressions are commonly used with Func, Action, Predicate, LINQ, and expression trees.

Q2. What is the difference between anonymous methods and lambda expressions?

Anonymous methods use the delegate keyword, whereas lambda expressions use the => operator. Both allow us to write anonymous functions, but lambda expressions provide shorter syntax and can be converted into expression trees when their form is supported. This makes lambda expressions particularly useful in LINQ and Entity Framework Core.

Easy way to remember:

Anonymous Method:
    delegate(int x) { return x * 2; }

Lambda Expression:
    x => x * 2

Both:
    Define anonymous functions

Major Difference:
    Lambda expressions support expression trees
    Anonymous methods do not
← Back to Articles