Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-08-03 20:25:33

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及 **闭包、委托、异步编程、捕获变量、线程安全** 和 **语言细节理解**,适合考察高级开发者的语言深度理解与实际问题解决能力。

---

### 🧠 面试题:闭包陷阱与异步执行

**题目:**

请看以下 C# 代码片段:

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

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

for (var i = 0; i < 10; i++)
{
tasks[i] = Task.Run(() =>
{
Console.WriteLine(i);
});
}

Task.WaitAll(tasks);
}
}
```

**问题:**

1. 这段代码会输出什么?为什么?
2. 如何修改这段代码,使得每个任务输出的是它被创建时的 `i` 值(即输出 0 到 9)?
3. 如果改为使用 `int i = 0;`(而不是 `var i = 0;`),结果会有什么不同?为什么?

---

### ✅ 参考答案(供面试官参考):

#### 1. 输出什么?为什么?

在 C# 中,`for` 循环变量 `i` 是**在循环外部声明的**,因此在 `Task.Run` 的 lambda 表达式中捕获的是**同一个变量 `i` 的引用**,而不是每次循环时的副本。

由于 `Task.Run` 是异步执行的,当这些任务真正运行时,主线程的 `for` 循环可能已经执行完毕,此时 `i == 10`。所以**输出的很可能是多个 `10`**,顺序不确定(因为任务调度是异步的)。

#### 2. 如何修改以输出 0 到 9?

在每次循环中,将当前的 `i` 值**复制到一个局部变量中**,这样每次 lambda 捕获的是一个新的变量实例:

```csharp
for (var i = 0; i < 10; i++)
{
int loop = i;
tasks[i] = Task.Run(() =>
{
Console.WriteLine(loop);
});
}
```

或者使用闭包传参方式(如将 `i` 作为参数传入):

```csharp
tasks[i] = Task.Run(() =>
{
Console.WriteLine(i);
}, i);
```

但注意,上面的 `Task.Run` 方法需要传入取消令牌,因此应使用以下方式:

```csharp
tasks[i] = Task.Run(() =>
{
Console.WriteLine(i);
});
```

或使用强制值捕获:

```csharp
for (int i = 0; i < 10; i++)
{
int capture = i;
tasks[i] = Task.Run(() => Console.WriteLine(capture));
}
```

#### 3. 如果改为 `int i = 0;`,结果会不同吗?

如果将循环写成:

```csharp
for (int i = 0; i < 10; i++)
{
tasks[i] = Task.Run(() => Console.WriteLine(i));
}
```

在 C# 5 及以后版本中,**`for` 循环变量的捕获行为已经改变**,每个循环迭代会创建一个新的变量实例。因此,这段代码在 C# 5+ 中会正确输出 0 到 9。

但在 C# 5 之前版本中,`i` 是在整个循环中共享的变量,结果仍然会是多个 `10`。

---

### 🧪 考察点总结:

| 考察点 | 描述 |
|--------|------|
| 闭包与变量捕获 | 理解 lambda 表达式如何捕获外部变量 |
| 异步执行与并发 | 理解多线程环境下变量的可见性和执行顺序 |
| C# 版本差异 | 熟悉 C# 5 对循环变量捕获的改进 |
| 语言细节 | 掌握 `var` 与 `int` 的作用域与生命周期区别 |
| 解决方案能力 | 能够写出线程安全且逻辑正确的代码 |

---

如果你需要更多类似难度的题目(如涉及表达式树、泛型约束、反射、协变逆变、模式匹配、记录类型等),我也可以继续提供。

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

上一篇: c#题例-2025-08-04 01:58:40

下一篇: c#题例-2025-08-03 14:52:02

精华推荐