列表中的 ArgumentsOutOfRangeExeption<T>

ArgumentsOutOfRangeExeption in a list<T>

我在调用该方法时抛出此异常。该列表恰好包含 52 个对象(卡片数量)。 有什么建议可能导致它吗?也许是 Add 和 RemoveAt 方法?或者也许是随机的? 编译器还告诉问题出在 deck.Add(temp[j]);线.

public void Shuffle()
        {
            List<Card> temp = new List<Card>();
            Random rand = new Random();
            for (int i = 0; i < 52; i++)
            {
                for (int j = rand.Next(i, 52); j < 52; j++)
                {
                    temp.Add(deck[j]);
                    deck.RemoveAt(j);
                    deck.Add(temp[j]);
                }
            }
       }

temp[j] 不一定存在。您需要初始化 temp 以便它至少有 j+1 个条目,或者您需要将 temp[j] 的行更改为更合适的内容。

当您调用 rand.Next(i, 52) 时,结果可能是 52,这将超出您的牌组和临时牌组的范围。

此外,正如@nvoigt 指出的那样,您需要初始化 temp 列表。 List 有一个构造函数,它接受一个整数作为初始大小。您可以传入 52。请参阅:http://msdn.microsoft.com/en-us/library/dw8e0z9z(v=vs.110).aspx.

您也可以通过在调试器中查看 j 的值自行轻松调试。

如果您想打乱项目列表,可以使用以下方法:

    public static void Shuffle<T>(IList<T> arr, Random rnd)
    {
        for (var i = 0; i < arr.Count; i++)
        {
            var j = rnd.Next(i, arr.Count);

            var tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }

此方法将帮助您在没有 ArgumentsOutOfRangeExeption 的情况下洗牌

好的,让我们假设我们正处于循环的第一个 运行。外循环和内循环的第一次迭代。 i0Rand(i, 52) 产生 13

所以我们有:

i - 0
j - 13
temp - empty list
deck - assume this is a list with 52 elements

现在让我们运行循环内的三行代码:

temp.Add(deck[j]);

获取deck的第13项,并将其添加到temp。 OK完成。 temp 现在有 1 个项目。

 deck.RemoveAt(j);

删除 deck 中的第 13 项。好的,好的。

 deck.Add(temp[j]);

获取 temp 中的第 13 项并将其添加到,等等,什么?1? temp只有1件商品! ExceptionException!.


首先不需要 temp 列表。有一个 very good shuffling algorithm 涉及遍历原始项目列表一次(而不是 N 次)。你只需要一个 temp 变量来保存一个值,同时将它与另一个交换。像这样:

public void Shuffle()
{
    Card temp;
    Random rand = new Random();
    for (int i = deck.Length; i >= 1; i--)
    {
        int j = rand.Next(0, i + 1);
        temp = deck[i];
        deck[i] = deck[j];
        deck[j] = temp;
   }
}

完成。