IEnumerable.ElementAt - Аргумент вне диапазона исключения, когда значение существует - PullRequest
2 голосов
/ 27 июня 2019

У меня есть этот кусок кода, который получает случайное число из счетчика списка (-1), а затем получает элемент по этому индексу. Затем я удаляю объект из этого списка, и код вызывается, пока все объекты не исчезнут из этого списка.

Я немного озадачен тем, как может быть 13 индексов (0-12), и целое число, которое я использую для получения элемента, равно 11. Как это может быть вне диапазона допустимых значений?

private Player GetRandomPlayer(List<Player> entries)
{
            var rIdx = rnd.Next(entries.Count - 1);
            var player = entries.Where(i => i.Seed == null).ElementAt(rIdx);
            entries.Remove(player);

            return player;            
}

Изображения исключений и контрольных примеров:

Список с 13 значениями: https://ibb.co/wQdq1q4

Исключение, включая int, используемое для получения значения: https://ibb.co/mJXwMFh

Ответы [ 2 ]

5 голосов
/ 27 июня 2019

Метод ElementAt() работает с возвращаемым значением вашего предложения 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);
3 голосов
/ 27 июня 2019

На выбор rIdx рассчитывается каждый ;но не каждый будет соответствовать предикату i => i.Seed == null.Поэтому, если в игре 13 игроков, 3 из которых не сыграны, и вы выбираете игрока 5 ... бум.

Исправлено: применить предикат до отсчета.

...