c#题例-2025-07-02 10:58:29
日期: 2025-07-02 分类: AI写作 16次阅读
当然可以!以下是一道**专家级别**的 C# 逻辑面试题,它结合了语言特性、面向对象设计、泛型编程和一些巧妙的陷阱,适合考察候选人对 C# 的深度理解以及逻辑分析能力。
---
### 🧠 面试题:泛型委托与闭包陷阱
#### 题目描述:
下面是一个使用 `Func
```csharp
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var actions = new List
for (int i = 0; i < 5; i++)
{
actions.Add(() => i);
}
foreach (var action in actions)
{
Console.Write(action() + " ");
}
}
}
```
---
#### 进阶问题(可选):
1. 如果将循环体改为:
```csharp
int copy = i;
actions.Add(() => copy);
```
输出会有什么不同?为什么?
2. 如何修改原始代码,使每个 lambda 表达式捕获的是当前迭代的值而不是变量本身?请提供至少两种解决方案。
---
### 💡 考察点解析:
- **闭包与变量捕获机制**:C# 中 lambda 表达式捕获的是变量本身,而非值。
- **延迟执行与副作用**:lambda 在添加到列表时不会立即执行,而是在调用时才执行。
- **值类型 vs 引用类型行为差异**
- **泛型委托的使用场景**
- **性能与内存管理意识**
---
### ✅ 标准答案:
#### 原始代码输出:
```
5 5 5 5 5
```
**原因解释:**
- 所有 lambda 表达式都捕获的是同一个变量 `i`,而不是每次迭代的副本。
- 循环结束后,`i` 的值为 5,此时所有 lambda 表达式引用的都是这个最终值。
- 所以在遍历执行时,它们读取的 `i` 都是 5。
---
#### 修改后的版本:
```csharp
int copy = i;
actions.Add(() => copy);
```
此时输出为:
```
0 1 2 3 4
```
**原因:**
- 每次迭代定义了一个新的局部变量 `copy`,它被分配一个新的存储位置。
- 每个 lambda 表达式捕获的是不同的 `copy` 变量,因此保留了当时的值。
---
### 🔁 解决方案汇总:
#### 方法一:引入中间变量复制值(如上所示)
#### 方法二:使用 `foreach` 替代 `for`(配合数组或集合)
```csharp
var values = new int[] { 0, 1, 2, 3, 4 };
var actions = new List
foreach (var v in values)
{
actions.Add(() => v);
}
// 输出: 0 1 2 3 4
```
> 注意:在 C# 5.0 及以后版本中,`foreach` 循环变量每次迭代都会创建一个新变量,避免了闭包陷阱。
---
如果你需要更多类似难度的问题(比如涉及协变逆变、反射、表达式树、async/await陷阱等),我可以继续提供。是否要再来一道?😊
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:AI写作
精华推荐