Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-06-26 09:58:44

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **闭包、委托、异步编程和捕获变量** 的深入理解,是考察候选人对 C# 语言机制和底层行为掌握程度的好题目。

---

### 🧠 面试题:你了解 `async/await` 和 `foreach` 中的变量捕获吗?

请看以下代码:

```csharp
using System;
using System.Threading.Tasks;
using System.Collections.Generic;

class Program
{
static async Task Main(string[] args)
{
var tasks = new List();

foreach (var i in new[] { 1, 2, 3 })
{
var delay = i * 1000;

Task task = Task.Run(async () =>
{
await Task.Delay(delay);
Console.WriteLine($"Value: {i}, Delay: {delay}");
});

tasks.Add(task);
}

await Task.WhenAll(tasks);
}
}
```

#### 问题:
- 这段程序运行后输出的结果会是什么?为什么?
- 如果将 `foreach (var i in ...)` 改为 `for (int i = 0; i < 3; i++)`,结果又会发生什么变化?解释其背后原理。

---

### ✅ 参考答案与解析:

#### 第一部分输出(使用 `foreach`):
可能输出如下(顺序不确定,因为是并发执行):

```
Value: 1, Delay: 1000
Value: 2, Delay: 2000
Value: 3, Delay: 3000
```

✅ 正确原因:

在 `foreach` 循环中,每次迭代都会创建一个新的循环变量 `i`(从 C# 5 开始),因此在 lambda 表达式中捕获的是当前迭代的值。所以每个任务都正确地捕获了对应的 `i` 值。

#### 第二部分修改为 `for` 后的变化:

```csharp
for (int i = 0; i < 3; i++)
{
int delay = i * 1000;

Task task = Task.Run(async () =>
{
await Task.Delay(delay);
Console.WriteLine($"Value: {i}, Delay: {delay}");
});

tasks.Add(task);
}
```

此时输出可能是:

```
Value: 3, Delay: 0
Value: 3, Delay: 1000
Value: 3, Delay: 2000
```

❌ 错误原因:

这是经典的 **变量捕获陷阱(captured variable trap)**。

- 在 `for` 循环中,变量 `i` 是在整个循环中复用的。
- 所有 lambda 表达式捕获的是同一个变量 `i`,而不是它的某个特定迭代时的值。
- 当任务真正执行的时候,`i` 已经变成 3 了(循环结束条件),所以所有任务中的 `i` 都是 3。

#### 如何修复?

只需在 `for` 循环内部引入一个局部变量即可:

```csharp
for (int i = 0; i < 3; i++)
{
int capturedI = i;
int delay = capturedI * 1000;

Task task = Task.Run(async () =>
{
await Task.Delay(delay);
Console.WriteLine($"Value: {capturedI}, Delay: {delay}");
});

tasks.Add(task);
}
```

这样就能确保每个 lambda 捕获的是正确的值。

---

### 🔍 考察点总结:

- 对 `foreach` 和 `for` 循环变量作用域的理解
- 掌握闭包(Closure)和变量捕获的行为差异
- 异步任务调度与延迟执行的时机
- 多线程环境中共享变量的风险
- 解决变量捕获陷阱的最佳实践

---

如果你需要更多类似难度级别的 C# 或 .NET 高级面试题,我可以继续为你出题 😊

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: c#题例-2025-06-26 15:31:52

下一篇: c#题例-2025-06-26 04:25:06

精华推荐