Lambda expressions
Write small methods inline with =>, understand type inference and closures, and use lambdas with List, sorting and LINQ.
Math.Sqrt to other methods. Writing a whole named method just to say “length greater than 6” is clumsy. A lambda expression is an unnamed method written right where it is needed.
Lambda syntax
| Form | Example |
|---|---|
() => DateTime.Now | |
x => x * x | |
(a, b) => a + b | |
(int a, int b) => a + b | |
b => { var kg = b.Length * 42.2; return kg > 300; } |
=> as “goes to”. The left side lists parameters, the right side is the body. A lambda has no type of its own: it becomes whatever delegate type the place it is used expects (Func<…>, Action<…>, Predicate<…>).
Lambdas everywhere
var beams = new List<Beam>{ new("B1", 6.0), new("B2", 4.5), new("B3", 7.2), new("B4", 8.0)}; Beam? b3 = beams.Find(b => b.Mark == "B3");bool anyShort = beams.Exists(b => b.Length < 5);int removed = beams.RemoveAll(b => b.Length > 7.5);beams.Sort((x, y) => y.Length.CompareTo(x.Length)); // longest first Console.WriteLine(b3);Console.WriteLine(anyShort);Console.WriteLine(removed);beams.ForEach(b => Console.Write(b.Mark + " ")); record Beam(string Mark, double Length);Beam { Mark = B3, Length = 7.2 }
True
1
B3 B1 B2Closures: capturing variables
int clicks = 0;Action onClick = () => clicks++; // captures 'clicks' onClick();onClick();Console.WriteLine(clicks); // the lambda changed the real variable Func<int> makeCounter(){ int count = 0; return () => ++count; // count lives on inside the lambda}var next = makeCounter();Console.WriteLine($"{next()} {next()} {next()}");2 1 2 3
static lambdas and discards
Func<double, double> square = static x => x * x; // 'static': can't capture anything (no hidden allocations)button.Click += (_, _) => Save(); // _ = parameter you don't useList<string> files = new() { "plan.dwg", "model.ifc", "notes.txt", "level2.ifc" };, use lambdas to (1) remove all files that are not .ifc, (2) sort the rest alphabetically, and (3) print them.
Show the solution
var files = new List<string> { "plan.dwg", "model.ifc", "notes.txt", "level2.ifc" }; files.RemoveAll(f => !f.EndsWith(".ifc", StringComparison.OrdinalIgnoreCase));files.Sort((a, b) => string.Compare(a, b, StringComparison.Ordinal));files.ForEach(f => Console.WriteLine(f));level2.ifc model.ifc
Remember
A lambda is an inline, unnamed method: (parameters) => body.Its delegate type is inferred from where it is used. Lambdas capture outside variables by reference (closures). Use them with Find,RemoveAll,Sort, events and LINQ.