C# IEnumerable.ElementAt-值存在时参数超出范围异常

C# IEnumerable.ElementAt-值存在时参数超出范围异常,c#,exception,ienumerable,C#,Exception,Ienumerable,我有一段代码,它从列表的计数(-1)中获取一个随机数,然后获取该索引处的元素。然后我从该列表中删除该对象,并调用该代码,直到所有对象都从该列表中删除 我有点困惑,为什么会有13个索引(0-12),而我用来获取元素的整数是11。这怎么可能超出有效值的范围 private Player GetRandomPlayer(列表条目) { var rIdx=rnd.Next(entries.Count-1); var player=entries.Where(i=>i.Seed==null).Elemen

我有一段代码,它从列表的计数(-1)中获取一个随机数,然后获取该索引处的元素。然后我从该列表中删除该对象,并调用该代码,直到所有对象都从该列表中删除

我有点困惑,为什么会有13个索引(0-12),而我用来获取元素的整数是11。这怎么可能超出有效值的范围

private Player GetRandomPlayer(列表条目)
{
var rIdx=rnd.Next(entries.Count-1);
var player=entries.Where(i=>i.Seed==null).ElementAt(rIdx);
删除(玩家);
返回球员;
}
异常和测试用例的图像:

列出13个值:


包括用于获取值的int的异常:

选择
rIdx
计算所有人;但并非所有人都将匹配谓词
i=>i.Seed==null
。所以如果有13名球员,3名非种子球员,你选择球员5。。。轰

修复:在计数之前应用谓词。

方法对
Where
子句的返回值起作用。如果少于
rIdx+1
元素具有
Seed==null
则会得到异常

通过假设你想要实现的目标,我认为这应该是可行的:

// filter list
var nullEntries = entries.Where(i => i.Seed == null).ToList();

// use only filtered values
var rIdx = rnd.Next(nullEntries.Count - 1);
var player = nullEntries[rIdx];
entries.Remove(player);

您的rIdx仅在条目列表中有效,不适用于仅包含Seed==null的子列表(除非条目的所有元素在该属性中都为null)
Where(i=>i.Seed==null)
apply filter on
entries
entries.Where(i=>i.Seed==null).Count()
很可能小于
13
ElementAt(rIdx)
将抛出超出范围的参数Exceptionminor note,但此处不需要
ref
。最好对现有玩家进行随机排序,然后从随机列表中删除第一个或最后一个玩家:random rand=new random();list sortedList=entries。选择(x=>new{player=x,rand=rand.Next()}).OrderBy(x=>x.rand).Select(x=>x.player).ToList();@JordanGW引用不是这样工作的;
List
是一个对象,所以即使您只有
列表条目
(无
ref
),调用代码正在将引用传递给列表;传递时列表本身不会被克隆-它只是列表引用的一个副本。
ref
在这里唯一允许的是:
GetRandomPlayer
更改
条目
以指向完全不同的列表对象,以及调用代码查看该重新分配。调用方和被调用方都将始终观察对现有对象的更改,无论是否使用
ref
,或者仅在谓词上使用Lastresult@Steve这可不是我所说的“随机”…但我想你永远无法确定:是的,它需要完全随机,所以每次代码运行时我都会得到不同的结果。请注意。谢谢。