InvalidOperationException Общая коллекция VB.Net? - PullRequest
0 голосов
/ 15 сентября 2011

Я знаю, что это вообще большое Нет-Нет для изменения коллекции, через которую вы перебираете, но, к сожалению, я не разработал код, который пытаюсь изменить. Повсюду делается следующее:

for each log in Logs
   logs.Delete(log.LogId)
Next

Удалить в значительной степени просто удаляет журнал из базы данных и удаляет его из коллекции. Ранее объект Logs использовал неуниверсальную коллекцию. Я изменил его, чтобы использовать коллекцию (журнала), чтобы я мог LINQify объекта. Теперь каждый раз, когда я вызываю next / .MoveNext вызывается после первого удаления, происходит следующая ошибка: InvalidOperationException: "Коллекция была изменена; операция перечисления может не выполняться."

Я понимаю, почему я получаю ошибку, но я не понимаю, почему это никогда не происходило с неуниверсальной версией. Есть ли способ обойти эту ошибку? Там действительно нет никакого способа, которым я могу потратить время, чтобы изменить каждое место, где удаляются журналы, как это (кодовая база велика). Я хотел бы просто удалить код в функции Delete, где он удаляет его из текущей коллекции, потому что я предполагаю, что ни один код ничего не делает с коллекцией после ее завершения, но вы знаете, что происходит, когда вы предполагаете.

Ответы [ 3 ]

1 голос
/ 15 сентября 2011

Ваша проблема в двух словах:

        Collection<object> stuff = new Collection<object> { 1, 2, 3, 4 };

        foreach (var o in stuff)
            stuff.Remove(o); // causes exception

Два решения:

  1. Сделайте копию коллекции и повторите ее.

        foreach (var o in stuff.ToArray())
            stuff.Remove(o); // does not cause exception
    
  2. Итерация коллекции в обратном направлении.

        for (int i = stuff.Count - 1; i >= 0; i--)
            stuff.RemoveAt(i); // does not cause exception
    

    (Это было бы что-то вроде logs.Delete(logs[i].LogId);)

Извините за C #, но концепции довольно ясны.

0 голосов
/ 15 сентября 2011

Ответ Чарльза заставил меня задуматься над созданием копии, а не перебирать реальную коллекцию.К сожалению, его решение потребовало бы изменить любой фрагмент кода, который удалял журналы активности, и это повсеместно.Вот как я исправил проблему, которая, кажется, прекрасно работает (Psuedocode):

До:

Public Function GetEnumerator() as IEnumerator
    Return col.GetEnumerator
End Function

После:

Public Function GetEnumerator() As IEnumerator
    Return col.ToList().GetEnumerator()
End Function
0 голосов
/ 15 сентября 2011

Вам не нужен цикл для удаления всех записей из Collection(Of T). Просто используйте метод Clear.

Logs.Clear
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...