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

Enumerable.Range(,)生成超范围值求助:从List<T>随机选9项

排查你的Enumerable.Range索引越界问题

嘿,这个问题我之前帮朋友排查过类似的,核心是你对Enumerable.Range的参数理解有误!

问题根源

你可能误以为Enumerable.Range(start, end)是生成从start到end的整数,但实际上它的第二个参数是要生成的元素总数,正确的签名是Enumerable.Range(int start, int count)。

看你的代码:

var targetIndexes = Enumerable.Range(i + 1, sellableItems.Count-1) 
                              .OrderBy(x => random.Next()) 
                              .Take(9) 
                              .ToArray();

这段代码会生成从i+1开始的、一共sellableItems.Count-1个连续整数。举个实际的例子:如果i的值是5000,而sellableItems.Count是31(小型List的合理大小),那生成的最大数值就是5000+1 + 31-1 -1 = 5030——这正好是你遇到的超出范围的数值!

而sellableItems的有效索引范围是0到sellableItems.Count-1(比如30),当targetIndexes里出现5030这种远大于列表最大索引的数值时,后续访问sellableItems[targetIndexes[j]]自然会抛出索引越界异常。

另外,你的逻辑目标是从sellableItems中随机选9项(看起来还要排除索引i?),但当前代码生成的范围和列表的有效索引完全不匹配,这才是问题的核心。

正确的实现方式

根据你的需求(排除索引i,从剩余元素中随机选9项),可以这样修改代码:

// 先获取所有有效索引,排除不需要的i
var validIndexes = Enumerable.Range(0, sellableItems.Count)
                             .Where(idx => idx != i);

// 打乱顺序后取最多9个
var targetIndexes = validIndexes.OrderBy(_ => random.Next())
                                .Take(9)
                                .ToArray();

for (var j = 0; j < targetIndexes.Length; j++)
{
    // 这里可以安全访问sellableItems[targetIndexes[j]]
}

如果不需要排除索引i,直接简化成:

var targetIndexes = Enumerable.Range(0, sellableItems.Count)
                             .OrderBy(_ => random.Next())
                             .Take(9)
                             .ToArray();

小补充:如果sellableItems的元素总数本身小于9,Take(9)会自动返回所有元素,不会触发异常,这点可以放心。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:33:13