C#递归方法持续引用同一局部变量 执行结果与预期不符求助
问题根源
你遇到的是两个C#特性叠加导致的问题:
- 闭包对循环变量的捕获规则:C#中for循环的迭代变量
i是整个循环作用域共享的,你在lambda表达式(_, j) => i != j里捕获的是这个共享变量,而非每次迭代时i的当前值。 - IEnumerable的惰性求值特性:
Where方法返回的序列不会立刻执行过滤逻辑,只有当你实际遍历该序列(比如最后调用ListToString拼接字符串时)才会真正计算过滤条件。
等到你的代码实际执行过滤逻辑时,for循环已经执行完毕,此时i的值已经变成了列表长度5,所有过滤条件j != 5永远为真,相当于没有做任何过滤,所以最终输出的都是完整的原始列表。
修复方案
只需要在for循环内部为每次迭代创建一个i的局部副本,让lambda捕获这个局部变量即可,同时建议将过滤后的序列立刻实例化为列表,避免后续惰性求值带来的其他意外:
public static IEnumerable<IEnumerable<T>> Foo<T>(IEnumerable<T> list) { var result = Enumerable.Empty<IEnumerable<T>>(); int count = list.Count(); if (count % 2 == 0) { result = result.Append(list); return result; } for (int i = 0; i < count; i++) { // 新增局部变量存储当前迭代的i值 int localI = i; // 过滤后立刻转为List,避免惰性求值 var filteredList = list.Where((_, j) => localI != j).ToList(); result = result.Concat(Foo(filteredList)); } return result; }
修改后运行即可得到预期输出。
内容的提问来源于stack exchange,提问作者DarkBarbarian
相关产品推荐
相关产品推荐

