You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中循环构建动态LINQ查询触发数组越界,手动编写正常

问题原因及解决方法

问题原因

这是闭包捕获变量引用而非值导致的经典问题。在循环中构建LINQ Where条件时,lambda表达式捕获的是position变量本身的引用,而非循环当前迭代的position数值。当后续调用ToList()执行查询时,循环已执行完毕,position的值会变为model.ExactMatches.Count(即5),此时访问x.Word[position]会超出5个字符单词的有效索引范围(0-4),从而触发数组越界异常。

解决方法

有两种常见的修复方式,核心都是让lambda捕获当前迭代的固定值而非循环变量的引用:

方法1:循环内创建局部变量保存当前索引值

GetAllWords();

var model = await req.ReadFromJsonAsync<SearchModel>();
var query = AllWords.AsQueryable();

for (var position = 0; position < model.ExactMatches.Count; position++)
{
  if (!string.IsNullOrWhiteSpace(model.ExactMatches[position]))
  {
    // 用局部变量捕获当前迭代的索引和目标字符
    var currentPosition = position;
    var targetChar = model.ExactMatches[currentPosition];
    Console.WriteLine($"  {currentPosition} = {targetChar}");
    query = query.Where(x => x.Word[currentPosition].ToString() == targetChar);
  }
}

var matches = query.ToList();

方法2:用foreach遍历带索引的集合项(更简洁)

GetAllWords();

var model = await req.ReadFromJsonAsync<SearchModel>();
var query = AllWords.AsQueryable();

// 过滤空项并同时获取索引与匹配字符
foreach (var (charMatch, position) in model.ExactMatches
    .Select((match, idx) => (match, idx))
    .Where(item => !string.IsNullOrWhiteSpace(item.match)))
{
  Console.WriteLine($"  {position} = {charMatch}");
  query = query.Where(x => x.Word[position].ToString() == charMatch);
}

var matches = query.ToList();

两种方法都能保证每个Where条件使用的是当前迭代的正确索引值,避免查询执行时出现索引越界。

内容的提问来源于stack exchange,提问作者Grandizer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:42:37