c#题例-2025-07-04 15:25:48
日期: 2025-07-04 分类: AI写作 34次阅读
当然可以!下面是一道**专家级别**的 C# 逻辑面试题,涉及 **委托、事件、闭包、线程安全、异步编程**等多个高级概念。这道题目不仅考察语法掌握程度,还考验对 .NET 运行时行为的理解和多线程编程的经验。
---
### 🧠 面试题:分析以下代码的输出并解释原因
```csharp
using System;
using System.Threading.Tasks;
class Program
{
delegate void MyDelegate();
static void Main(string[] args)
{
MyDelegate del = null;
for (int i = 0; i < 5; i++)
{
int captured = i;
Task.Run(() =>
{
del += () => Console.WriteLine(captured);
}).Wait();
}
// Fire the delegate
del?.Invoke();
}
}
```
---
### ❓问题:
1. 该程序的最终输出是什么?
2. 如果将 `del += ...` 改为 `del = del + ...`,是否会影响结果?为什么?
3. 如何修改这段代码以确保线ambda表达式中捕获的变量是确定性的(即不出现意外值)?
---
### 💡考查点:
- **闭包与变量捕获机制**
- **Task.Run 的同步执行(使用 Wait())的影响**
- **委托链的合并(+= vs = delegate +)**
- **线程安全性和副作用**
- **C# 中值类型变量在 lambda 表达式中的捕获方式**
---
### ✅参考答案概要:
#### 1. 输出结果:
由于每个任务都通过 `.Wait()` 同步执行完毕,所以 `captured` 在每次循环中被赋值为当前 `i` 的副本(因为是局部变量),因此闭包捕获的是稳定的值。
最终 `del` 是一个包含 5 个方法调用的多播委托,调用 `del.Invoke()` 会依次打印:
```
0
1
2
3
4
```
#### 2. `del +=` 和 `del = del +` 的区别:
在 C# 中:
- `del += x` 是线程不安全的,它等价于 `del = del + x`。
- 在多线程环境下,如果多个线程同时执行 `del +=` 操作,可能会导致委托丢失更新。
- 但在本例中,所有操作都是串行完成的(因为用了 `.Wait()`),所以两者效果相同。
#### 3. 确保捕获变量确定性:
本例已经做到了捕获确定值,因为使用了 `int captured = i;` 显创建了一个新的变量用于闭包捕获,而不是直接捕获循环变量 `i`。
如果是这样写:
```csharp
for (int i = 0; i < 5; i++)
{
Task.Run(() => del += () => Console.WriteLine(i));
}
```
那么所有的 lambda 都会引用同一个 `i`,最后可能全部输出 `5`。
---
### 🎯总结评价标准:
| 能力维度 | 考察点 |
|----------|--------|
| 基础语法 | 对委托、lambda、Task 的基本理解 |
| 进阶理解 | 变量捕获、闭包、多播委托的运作机制 |
| 多线程 | 是否注意到线程安全及顺序执行的问题 |
| 实战经验 | 是否能提出优化建议或潜在陷阱 |
---
如果你需要更多类似级别的题目,比如涉及 **LINQ 性能优化、Expression Tree 构建、反射 Emit、泛型协变逆变、GC 生命周期管理**等方面的内容,我也可以继续出题 😊
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐