# Lambda Expressions

A lambda expression is a small method with no name, written where it's used, such as name => name.Length > 4. Pass one to a method like FindAll, RemoveAll or Sort, and that method runs it on each item.

Apprentice · C# · Updated November 3, 2026

## After this lesson you can

- Write a lambda expression with its parameters, an arrow and a body, and read one aloud
- Pass a lambda to a method such as FindAll, RemoveAll, Exists or Sort

## Key takeaways

- A lambda such as `name => name.Length > 4` is a method with no name: its parameters, the `=>` arrow, then its body. Read `=>` aloud as "goes to" or "such that".
- Pass a lambda to `FindAll`, `Find`, `Exists` or `RemoveAll`, and the method does the looping while your lambda decides about one item at a time.
- Two parameters go in parentheses, as in `names.Sort((a, b) => a.Length.CompareTo(b.Length))`; a body with more than one statement needs braces and a `return`.
- A `Func<string, bool>` holds a lambda that takes a `string` and returns a `bool` (the last type is the return type); an `Action<string>` returns nothing.

Some methods need to be told **how** to do part of their job. A list can find every name you want, but it can't know which names you want. So you hand it a tiny method that answers *"is this one of them?"* for a single name, and the list runs it on each one.

Writing a whole named method for that would be a lot of ceremony for one line. A **lambda expression** is the short form: a small method with no name, written right where it's used.

## The shape of a lambda

```csharp
name => name.Length > 4
```

Read the `=>` aloud as **"goes to"** or **"such that"**: *name such that name's length is more than 4*.

| Part | Here | Means |
|---|---|---|
| Parameters, before the arrow | `name` | What the lambda is given: one name |
| The arrow | `=>` | Separates the parameters from the body |
| The body, after the arrow | `name.Length > 4` | What it works out: `true` or `false` |

It's the same as this method, minus the name, the types and the `return`:

```csharp
bool IsLong(string name)
{
    return name.Length > 4;
}
```

C# works out the parameter's type from where the lambda is used, so you rarely write it.

## Giving a lambda to a method

`List<T>` has methods that take a lambda. **`FindAll`** runs it on each item and returns a new list of the items it said `true` for:

```csharp
List<string> names = new List<string> { "Olivia", "Ethan", "Ava", "Liam", "Sophia", "Mia" };

List<string> longNames = names.FindAll(name => name.Length > 4);
List<string> startWithA = names.FindAll(name => name.StartsWith("A"));

Console.WriteLine(string.Join(", ", longNames));
Console.WriteLine(string.Join(", ", startWithA));
```

```text
Olivia, Ethan, Sophia
Ava
```

Each call gets a different lambda, so each finds different names. `FindAll` does the looping; the lambda only decides about one name at a time.

More `List<T>` methods that take one:

```csharp
List<int> scores = new List<int> { 72, 95, 48, 88, 61 };

Console.WriteLine(scores.Exists(score => score >= 90));
Console.WriteLine(scores.Find(score => score < 50));

scores.RemoveAll(score => score < 60);
Console.WriteLine(string.Join(", ", scores));
```

```text
True
48
72, 95, 88, 61
```

| Method | Runs the lambda on each item, and |
|---|---|
| `FindAll(...)` | returns a new list of the items it's `true` for |
| `Find(...)` | returns the first item it's `true` for (or the default, such as `null` or `0`) |
| `Exists(...)` | returns `true` if it's `true` for any item |
| `RemoveAll(...)` | removes every item it's `true` for, and returns how many |

## More than one parameter

When a lambda needs two parameters, put them in parentheses. **`Sort`** compares two items at a time, and needs to know which goes first:

```csharp
List<string> names = new List<string> { "Olivia", "Ethan", "Ava", "Liam" };

names.Sort((a, b) => a.Length.CompareTo(b.Length));

Console.WriteLine(string.Join(", ", names));
```

```text
Ava, Liam, Ethan, Olivia
```

`a.Length.CompareTo(b.Length)` is negative when `a` is shorter, so shorter names go first.

And when the body needs more than one statement, give it braces and a `return`, like a method's body:

```csharp
List<int> scores = new List<int> { 72, 95, 48, 88 };

List<int> passes = scores.FindAll(score =>
{
    bool passed = score >= 60;
    return passed;
});

Console.WriteLine(passes.Count);
```

```text
3
```

## Lambdas in variables

A lambda can be kept in a variable, and called like a method. Its type says what it takes and returns: **`Func<string, bool>`** takes a `string` and returns a `bool` (the last type is always the return type), and **`Action<string>`** takes a `string` and returns nothing:

```csharp
Func<int, int> square = number => number * number;
Func<string, bool> isLong = name => name.Length > 4;
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");

Console.WriteLine(square(7));
Console.WriteLine(isLong("Ava"));
greet("Ada");
```

```text
49
False
Hello, Ada!
```

`Func` and `Action` are **delegates**: types for "a method that takes these and returns that". You won't often write them yourself, but you'll see them in the descriptions of methods that take lambdas, such as `Where(Func<T, bool> predicate)` in the next lesson.

## Check yourself

2 questions to try on the lesson page.

## So what

A lambda is a method small enough to write in the middle of a line. Hand one to a method, and that method does the looping while your lambda makes the decision. That's the whole idea behind LINQ, next.

## Key terms

- [Lambda Expression](https://www.ask-codey.com/glossary/lambda-expression-c-sharp)
- [Delegate](https://www.ask-codey.com/glossary/delegate)

## Cheat sheets

- [Lambda Expressions](https://www.ask-codey.com/cheat-sheets/linq-lambda-expressions-cheat-sheet)

Source: https://www.ask-codey.com/lessons/linq-lambda-expressions
