Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-14 18:32:53

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **闭包、委托、异步编程和变量捕获机制**,这些都是考察候选人对 C# 深层理解的经典点:

---

### 🧠 面试题:闭包与异步任务中的变量捕获陷阱

**题目如下:**

请分析以下 C# 控制台程序的输出,并解释原因。然后提出一种修改方式以达到预期效果。

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

class Program
{
static async Task Main(string[] args)
{
for (var i = 0; i < 5; i++)
{
Task.Run(async () =>
{
await Task.Delay(100); // 模拟异步工作
Console.WriteLine(i);
});
}

await Task.Delay(1000); // 等待所有任务完成
}
}
```

---

### ✅ 考察点解析:

- **变量捕获(Variable Capturing)机制**
- **值类型 vs 引用类型的捕获差异**
- **异步 lambda 表达式中闭包的行为**
- **如何正确地在循环中捕获当前变量值**

---

### 📌 可能的输出:

由于 `i` 是在循环外部被捕获的,所有任务最终都会打印 **5**,因为循环执行完毕后 `i` 的值已经是 5。

输出可能是:
```
5
5
5
5
5
```

---

### ✍️ 解答建议:

#### 为什么是 5?

- `i` 使用的是 `var`(注意不是 `int`),但在 C# 中 `var i = 0` 会被推断为 `int`。
- 所有任务都引用了同一个变量 `i`,而这个变量在循环结束后已经变成了 5。
- 当任务真正执行时,它们读取的是此时的 `i` 值。

#### 如何修正?

在每次循环中创建一个副本:

```csharp
for (var i = 0; i < 5; i++)
{
int copy = i;
Task.Run(async () =>
{
await Task.Delay(100);
Console.WriteLine(copy);
});
}
```

这样每个闭包都捕获了不同的局部变量副本,输出就会变成:

```
0
1
2
3
4
```

---

### 🎯 扩展问题(进阶讨论):

- 如果将 `var` 改为 `int`,行为是否改变?为什么?
- 如果使用 `foreach` 替代 `for`,结果会不同吗?(C# 5.0 之后有变化)
- 在 .NET Core/.NET 5+ 下运行此代码,结果是否有不同?
- 如何使用 `async/await` 正确等待所有任务完成?

---

如果你需要更多类似级别的题目,比如涉及表达式树、反射 Emit、泛型约束、协变逆变、线程同步上下文等,请告诉我,我可以继续出题 😄

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

上一篇:无

下一篇: c#题例-2025-07-14 12:59:39

精华推荐