Lambda expressions in C# provide a concise way to represent anonymous methods using special syntax. They are used extensively in LINQ and other places where short snippets of code are required. This tutorial covers what lambda expressions are, how to use them, and provides a detailed explanation of their internal workings with an equivalent method representation.
Lambda expressions are a shorthand syntax for writing anonymous methods. They are particularly useful for writing inline code that can be passed as arguments to methods.
Syntax:
(parameters) => expression
(parameters) => { statements }
Let's start with a simple example of using a lambda expression to square a number.
Lambda Expression:
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
// Lambda expression to square a number
Func<int, int> square = x => x * x;
int result = square(5);
Console.WriteLine(result); // Output: 25
}
}
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
// Equivalent method to square a number
int result = Square(5);
Console.WriteLine(result); // Output: 25
}
static int Square(int x)
{
return x * x;
}
}
Lambda expressions are often used with LINQ to perform operations like filtering, selecting, and transforming data.
Example:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// Using lambda expression with LINQ to filter even numbers
var evenNumbers = numbers.Where(n => n % 2 == 0);
foreach (var number in evenNumbers)
{
Console.WriteLine(number); // Output: 2, 4, 6
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// Using a method to filter even numbers
var evenNumbers = numbers.Where(IsEven);
foreach (var number in evenNumbers)
{
Console.WriteLine(number); // Output: 2, 4, 6
}
}
static bool IsEven(int n)
{
return n % 2 == 0;
}
}
Let's implement a custom `Where` method to demonstrate how lambda expressions work behind the scenes.
Custom Where Method:
using System;
using System.Collections.Generic;
namespace LambdaExamples;
public static class EnumerableExtensions
{
public static IEnumerable<T> CustomWhere<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
}
using System;
using System.Collections.Generic;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// Using custom Where method to filter even numbers
var evenNumbers = numbers.CustomWhere(n => n % 2 == 0);
foreach (var number in evenNumbers)
{
Console.WriteLine(number); // Output: 2, 4, 6
}
}
}
Here is a table of some commonly used built-in lambda methods in C#:
Method | Description | Example |
---|---|---|
Where |
Filters a sequence of values based on a predicate. | var evens = numbers.Where(n => n % 2 == 0); |
Select |
Projects each element of a sequence into a new form. | var squares = numbers.Select(n => n * n); |
FirstOrDefault |
Returns the first element of a sequence, or a default value if no element is found. | var first = numbers.FirstOrDefault(n => n > 10); |
OrderBy |
Sorts the elements of a sequence in ascending order. | var sorted = numbers.OrderBy(n => n); |
GroupBy |
Groups the elements of a sequence according to a specified key selector function. | var grouped = numbers.GroupBy(n => n % 2); |
Aggregate |
Applies an accumulator function over a sequence. | var sum = numbers.Aggregate((a, b) => a + b); |
Let's look at some more examples of lambda expressions in action.
Sorting with Lambda Expressions:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 3, 1, 4, 1, 5, 9 };
// Using lambda expression to sort numbers in ascending order
var sortedNumbers = numbers.OrderBy(n => n);
Console.WriteLine("Sorted Numbers:");
foreach (var number in sortedNumbers)
{
Console.WriteLine(number); // Output: 1, 1, 3, 4, 5, 9
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 3, 1, 4, 1, 5, 9 };
// Using lambda expression to find the maximum value
int maxNumber = numbers.Max();
Console.WriteLine($"Maximum Number: {maxNumber}"); // Output: Maximum Number: 9
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Using lambda expression to calculate the sum of numbers
int sum = numbers.Sum();
Console.WriteLine($"Sum: {sum}"); // Output: Sum: 15
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace LambdaExamples;
class Program
{
static void Main(string[] args)
{
List<string> words = new List<string> { "apple", "banana", "cherry", "date", "elderberry", "fig", "grape" };
// Using lambda expression to group words by their first letter
var groupedWords = words.GroupBy(word => word[0]);
Console.WriteLine("Grouped Words:");
foreach (var group in groupedWords)
{
Console.WriteLine($"Group {group.Key}:");
foreach (var word in group)
{
Console.WriteLine($" {word}");
}
}
}
}
Lambda expressions provide a powerful and concise way to write inline code, making it easier to work with collections and perform operations. By understanding how they are translated into methods, you can better appreciate their efficiency and utility.