CodeGym /课程 /C# SELF /Lambda 表达式的语法 ( =>)...

Lambda 表达式的语法 ( =>)

C# SELF
第 49 级, 课程 1
可用

1. 介绍

你可能不知道,但面试里最爱问的问题之一就是 “你对 lambda 表达式了解多少?” 为啥问这个?因为它在 C# 里超方便、很“时髦”,能写更少、更有表达力的代码。如果匿名方法是像手写信件,lambda 表达式就像发即时消息:快、简洁,有时候还能带个表情(差不多就是这样)。

lambda 表达式从 C# 3.0 开始引入,从那以后到处都是:在 LINQ、事件处理、并行、集合,甚至一些 .NET 的 AI 库里都用得到。

lambda 表达式 是直接在代码里“就地”声明方法的一种方式,没有名字,简短明了。基本语法通常是:

(参数) => 表达式_或_代码块

这个“箭头” => 叫做 “lambda 操作符” 或 “箭头”。

小小比喻

想象你写个食谱:“取个苹果,切一切,放到碗里”。
在 C# 中可能就是:

(苹果) => 切(苹果)

2. 把匿名方法改成 lambda

假设我们有一个委托:

delegate int SquareDelegate(int x);

匿名方法看起来会像这样:

SquareDelegate sq = delegate(int x) {
    return x * x;
};

现在用 lambda 写一遍:

SquareDelegate sq = (int x) => { return x * x; };

但 C# 能推断类型,我们可以再简化:

SquareDelegate sq = x => x * x;

惊人的简洁!

和“常规”方法与匿名函数比较

方式 声明位置 可以在哪里使用 缺点
命名方法 在类里 任何地方 需要名字,代码较多
匿名方法 在代码中 只能与委托一起使用 语法更啰嗦
lambda 表达式 在代码中 与委托一起的任何地方都能用 有时类型不明显

3. lambda 语法:几种变体

参数

无参数:

Action hello = () => Console.WriteLine("你好,世界!");

单参数(可以省略括号):

Func<int, int> inc = x => x + 1;

多个参数(需要括号):

Func<int, int, int> sum = (a, b) => a + b;

lambda 的主体

单表达式 — 不用大括号,也不用 return:

x => x * x

代码块 — 用大括号,需要 return:

(x, y) =>
{
    int z = x + y;
    return z * z;
}

参数类型

大多数情况下不需要显式写类型 — 编译器会推断。但如果你想写,也可以:

(x, y) => x + y      // 编译器会推断类型.
(int x, int y) => x + y  // 也可以显式写类型.

4. 细节和更实际的例子

与集合一起使用

记得我们的小练习(比如用户列表)吗?假设有个整型数组:

int[] numbers = { 1, 2, 3, 4, 5 };

需要筛选出偶数:

var evenNumbers = numbers.Where(n => n % 2 == 0);

这里 Where 是 LINQ 的扩展方法,条件就是我们的 lambda 过滤器。

作为参数传递给方法

假设我们有个委托方法:

public delegate bool Filter(int number);

public static int[] FilterNumbers(int[] data, Filter predicate)
{
    var result = new List<int>();
    foreach (var n in data)
        if (predicate(n))
            result.Add(n);
    return result.ToArray();
}

现在传入一个 lambda:

int[] evens = FilterNumbers(numbers, n => n % 2 == 0);

把 lambda 当成事件处理器

button.Click += (sender, args) => Console.WriteLine("按钮被点击!");

5. lambda 与标准泛型委托

说到 lambda 就离不开 Func<>, Action<> 和 Predicate<>。它们是常用的委托类型:

  • Action — 不返回值。
  • Func — 返回值。
  • Predicate — 返回 bool,通常用于筛选。

Action 示例:

Action<string> log = message => Console.WriteLine(message);

log("这是通过 lambda 的消息!");

Func 示例:

Func<int, int, int> multiply = (a, b) => a * b;
int product = multiply(3, 5); // 15

Predicate 示例:

Predicate<int> isNegative = n => n < 0;

bool test = isNegative(-7); // true

6. 多表达式的 lambda:什么时候需要代码块

如果 lambda 要做多步操作,用大括号并显式写 return:

Func<int, int, string> describeSum = (a, b) =>
{
    int sum = a + b;
    return $"总和: {sum}";
};

要是没写 return,编译器会抱怨(但不会讲太明白原因——就会说“并非所有路径都有返回值”)。

7. 返回 void:Action

当 lambda 不返回东西时,用 Action:

Action greet = () => Console.WriteLine("笑一笑 — 代码能编译通过!");

lambda 可以包含任意多条语句:

Action<int> printSquare = x =>
{
    int sq = x * x;
    Console.WriteLine($"数字 {x} 的平方是 {sq}");
};

8. 限制和常见错误

有时候你想随便写 lambda,但编译器不一定买账。

不能声明一个与外部已捕获变量同名的变量。

注意类型:如果委托签名和 lambda 不匹配,会报错。

如果委托要求返回值,就必须返回。

复杂的 lambda 别忘了大括号。单表达式 — 不用括号也不用 return。多条语句 — 用括号并显式 return。

2
任务
C# SELF, 第 49 级, 课程 1
已锁定
带有多个参数的 Lambda 表达式实现数字相加
带有多个参数的 Lambda 表达式实现数字相加
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION