Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >AI写作

c#题例-2025-07-17 04:31:59

当然可以!下面是一道**专家级别**的 C# 程序员逻辑面试题,涉及到 **委托、泛型、闭包、线程安全和延迟执行**等多个高级概念:

---

### 🧠 面试题:理解委托链与闭包捕获

#### 问题描述:

请看以下代码片段:

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

class Program
{
static void Main()
{
var actions = new List();

for (int i = 0; i < 5; i++)
{
Task.Delay(10).Wait(); // 模拟异步操作,不影响逻辑

int captured = i;

actions.Add(() =>
{
Console.WriteLine($"i: {i}, captured: {captured}");
});
}

Parallel.Invoke(actions.ToArray());
}
}
```

#### 问题如下:

1. **输出结果是什么?为什么?**
2. 如果将 `int captured = i;` 改为 `var captured = i;` 是否会影响结果?为什么?
3. 如何修改该代码以确保每个 `Action` 输出的是循环当时的 `i` 值(即 0 到 4)?
4. 如果使用 `Task.Run` 替代 `Parallel.Invoke`,会出现什么潜在问题?如何解决?

---

### 💡 考察点解析:

| 考察点 | 解析 |
|--------|------|
| 闭包捕获 | 使用 lambda 表达式时对外部变量的捕获机制 |
| 变量捕获陷阱 | 在循环中直接捕获循环变量 `i` 会导致所有委托看到的是最终值 |
| 值类型 vs 引用类型 | 捕获 `int` 是值类型,但闭包会提升为类字段,导致共享状态 |
| 并行执行 | `Parallel.Invoke` 会并发执行委托,涉及线程调度和输出顺序不确定 |
| 泛型委托 | Action 的使用方式及其生命周期管理 |

---

### ✅ 参考答案简要:

1. **输出可能类似:**

```
i: 5, captured: 0
i: 5, captured: 1
i: 5, captured: 2
i: 5, captured: 3
i: 5, captured: 4
```

- 因为 `i` 是在闭包中被捕获的,而不是在每次迭代中复制。当委托执行时,`i` 已经变成 5。
- `captured` 是每次迭代定义的新变量,因此正确保存了当时的值。

2. **`var captured = i;` 不影响结果。**
因为 `var` 只是类型推断,底层仍是 `int captured = i;`。

3. **修复方法:**

```csharp
for (int i = 0; i < 5; i++)
{
int captured = i;
actions.Add(() => Console.WriteLine($"captured: {captured}"));
}
```

或者使用局部函数/创建新作用域。

4. **使用 `Task.Run` 的问题:**
- 多个任务并行执行时,`Console.WriteLine` 是线程安全的,但输出可能会交错。
- 更严重的是,如果在 WinForm/WPF 中未捕获异常或未等待任务完成,可能导致程序提前退出。

---

如果你需要更偏向“设计模式”、“反射”或“性能优化”的专家级题目,也可以告诉我,我可以继续出一道 😄

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

上一篇:无

下一篇: c#题例-2025-07-16 22:58:27

精华推荐