Подтвердить что ты не робот

Удалить элемент из списка и получить элемент одновременно

В С# я пытаюсь получить элемент из списка со случайным индексом. Когда он был извлечен, я хочу, чтобы он был удален, чтобы он больше не мог быть выбран. Кажется, мне нужно много операций для этого, нет ли функции, в которой я могу просто извлечь элемент из списка? функция RemoveAt (index) недействительна. Я хотел бы получить значение с возвратом.

Что я делаю:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int index = rand.Next(numLst.Count);
  int extracted = numLst[index]; 
  // do something with extracted value...
  numLst.removeAt(index);
}
while(numLst.Count > 0);

Что я хотел бы сделать:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int extracted = numLst.removeAndGetItem(rand.Next(numLst.Count)); 
  // do something with this value...
}
while(numLst.Count > 0);

Существует ли такая функция removeAndGetItem?

4b9b3361

Ответ 1

Нет, поскольку это нарушение этикета чистой функции, когда метод либо имеет побочный эффект, либо возвращает полезное значение (т.е. Не просто указывает на состояние ошибки) - никогда не бывает и того, и другого.

Если вы хотите, чтобы функция отображалась как атомарная, вы можете получить блокировку в списке, которая не позволит другим потокам получать доступ к списку во время его изменения, при условии, что они также используют lock:

public static class Extensions
{
    public static T RemoveAndGet<T>(this IList<T> list, int index)
    {
        lock(list)
        {
            T value = list[index];
            list.RemoveAt(index);
            return value;
        }
    }
}

Ответ 2

public static class ListExtensions
{
  public static T RemoveAndGetItem<T>(this IList<T> list, int iIndexToRemove}
  {
    var item = list[iIndexToRemove];
    list.RemoveAt(iIndexToRemove);
    return item;
  } 
}

Они называются методы расширения, вызывают как new List<T>().RemoveAndGetItem(0).

Что следует учитывать в методе расширения

Обработка исключений с переданным вами индексом, убедитесь, что индекс выполняет 0 и подсчет списка перед этим.