C# Anonymous methods and lambda expressions

Named method vs anonymous method

A named method is a method that can be called by its name:

// named method declaration
public string Join(string s1, string s2)
{
	return s1+s2;
}
// named method usage
var result = Join("this is ", "a joined string");

An anonymous method is a method that is passed as an argument to a function, without the need for its name. These methods can be constructed at runtime or be evaluated from a lambda expression.

// declaration
public void ProcessBook(Action<Book> process, List<Book> books)
{
	foreach (Book b in books)
	{
		process(b);
	}
}
// usage - print book titles
ProcessBook(bookList, book => Console.WriteLine(book.Title))

Here book => Console.WriteLine(book.Title) is the lambda expression and it’s result is an anonymous function that will be run by the method ProcessBook

Lamdba expressions

You use a lambda expression to create an anonymous method.

We use => to separate the lambda’s (optional) params list from its body. It can be any this 2 forms:

// lambda expression: has an expression as its body
(input-params) => expression

// lambda statement: has a statement block as its body
(input-params) => { sequence-of-statements }

Any lambda expression can be converted to a delegate type. The types of its parameters and return value define the delegate type.

  • If a lambda expression just consumes a class and it doesn’t return a value, it can be converted to Action<T>. (a lambda that consumes 2 classes and doesn’t return anything can be converted to Action<T1,T2>)
  • If the lambda consumes a class and returns a bool value, it can be converted to Predicate<T>
  • If it consumes a class and returns anything else, it can be converted to Func<T,K>

lambda statement with 0 params

Action line = () => Console.WriteLine();

lambda with 1 param

Func<double, double> cube = x => x * x * x;

lambda with 2 or more params

Func<int, int, bool> testForEquality = (int x, int y) => x == y;

default values for lambdas

From c# 12 on you can provide default values for params on lambda expressions.

var incrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(IncrementBy(5)); // 6
Console.WriteLine(IncrementBy(5, 2)); // 7

Reference(s)

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions
https://stackoverflow.com/questions/20869312/c-anonymous-method-vs-named-method