C# --- Lambda Expression
Intro to Lambda Expression
- 在编程中, lambda表达式是实现匿名函数的一种方法
- lambada表达式可以增强代码的可读性. 当需要定义一些短小内容简单的函数的时候, 专门给这些方法起一个名字就显得麻烦且不必要, 这时就可以用lambda表达式替代
- lambda表达式分为两种: expression lambda 和 statement lambda
expression Lambda
//(parameters) => expression
//expression lambda 直接返回 expression的结果
//Example:
(int num) => num * 5;
statement lambda
//(parameters) => { statements; }
//statement lambda 需要显式的写出return value. 否则没有返回值
//Example
(int a, int b) =>
{
var sum = a + b;
return sum;
};
lambda表达式的参数
- 如果没有参数, 则括号里为空:
Action line = () => Console.WriteLine();
- 如果只有一个参数, 则可以不加括号:
Func<double, double> cube = x => x * x * x;
- 多个参数用逗号隔开:
Func<int, int, bool> testForEquality = (x, y) => x == y;
(Func最后一个参数 bool为返回值)
lambda表达式参数的自动推断
- 在编写Lambda表达式时,通常不必为输入参数指定类型,因为编译器可以根据Lambda的主体、参数类型和其他因素推断类型
- 比如 如果你正在查询一个
IEnumerable<Customer>
,那么输入变量将被推断为Customer对象,这意味着你可以访问它的方法和属性customers.Where(c => c.City == "London");
- Lambda表达式的类型推断一般遵循以下规则:
- Lambda表达式中的参数数量必须与委托类型相同。
- Lambda表达式中的每个输入参数必须可以隐式转换为对应的委托参数。
- Lambda表达式的返回值(如果有)必须可以隐式转换为委托的返回类型。
lambda表达式的返回值
- expression lambda 直接返回 expression的结果
- statement lambda 需要显式的写出return value. 否则没有返回值
- 通常情况下,Lambda表达式的返回类型是明显且可推断的。然而,对于某些表达式,这种推断可能不起作用
var choose = (bool b) => b ? 1 : "two"; // ERROR: Can't infer return type
- 从C# 10开始,你可以在输入参数之前指定Lambda表达式的返回类型。当你指定显式的返回类型时,你必须在输入参数周围加上括号
var choose = object (bool b) => b ? 1 : "two"; // Func<bool, object>
如何使用lambda Expression
- lambda表达式一般和委托结合使用, 也就是用lambda定义委托或者将lambda表达式直接作为方法传参
Example 1: Action委托
Action<string> greet = name =>
{
string greeting = $"Hello {name}!";
Console.WriteLine(greeting);
};
greet("World");
// Output:
// Hello World!
Example 2: Func委托
Func<int, int> square = x => x * x;
Console.WriteLine(square(5));
// Output:
// 25
Func<int, int, bool> testForEquality = (x, y) => x == y;
Console.WriteLine(testForEquality(5, 7));
// Output:
// False
Func<int, string, bool> isTooLong = (x, s) => s.Length > x;
Console.WriteLine(testForEquality(3, "hello"));
// Output:
// True
Example 3: Natural type of a lambda expression
- 从C# 10开始, lambda expression不需要必须定义成一种委托类型, 比如
Func
或者Action
.
而是可以定义成var类型, 然后由编译器自己推断类型.
//会自动转换成 Func<string, int> 类型
var parse = (string s) => int.Parse(s);
//会自动转换成 Func<int, int, int> 类型
var IncrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(IncrementBy(5)); // 6
Console.WriteLine(IncrementBy(5, 2)); // 7
//但是必须要有足够的信息才能自动转换
var parse = s => int.Parse(s); // ERROR: Not enough type info in the lambda
Example 4 : 使用lambda作为委托传参 — LINQ
using System;
using System.Collections.Generic;
using System.Linq;
class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
class demo{
static void Main()
{
List<Dog> dogs = new List<Dog>() {
new Dog { Name = "Rex", Age = 4 },
new Dog { Name = "Sean", Age = 0 },
new Dog { Name = "Stacy", Age = 3 }
};
var names = dogs.Select(x => x.Name);
foreach (var name in names)
{
Console.WriteLine(name);
}
Console.Read();
}
}
var sortedDogs = dogs.OrderByDescending(x => x.Age);
foreach (var dog in sortedDogs)
{
Console.WriteLine(string.Format("Dog {0} is {1} years old.", dog.Name, dog.Age));
}