2010-07-30 2 views
4

Моя цель - удалить пользователя из списка пользователей в моем приложении. Но я не могу дотянуться до этой ошибки. Какой-то плз меня выручит.C#: коллекция была изменена; операция перечисления может не выполняться

if (txtEmailID.Text.Length > 0) 
{ 
    users = UserRespository.GetUserName(txtEmailID.Text); 
    bool isUserAvailable=false; 
    foreach (EduvisionUser aUser in users) // Exception thrown in this line 
    { 
     isUserAvailable = true; 
     if(!aUser.Activated) 
     { 
      users.Remove(aUser); 
     } 
    } 
    if (users.Count == 0 && isUserAvailable) 
    { 
     DeactivatedUserMessage(); 
     return; 
    } 
} 

ответ

7

Вы пытаетесь удалить пользователя из списка, в котором вы работаете.

это невозможно. Лучше всего, чтобы создать новый список и добавить хорошие в нем вместо удаления плохих

if (txtEmailID.Text.Length > 0) 
    { 
     //@new list 
     List<EduvisionUser> listOfAcceptedUsers = new List<EduvisionUser>()** 

     users = UserRespository.GetUserName(txtEmailID.Text); 
     bool isUserAvailable=false; 
     foreach (EduvisionUser aUser in users) --->***Exception thrown in this line*** 
     { 
      isUserAvailable = true; 

      //Add user to list instead of deleting 
      if(aUser.Activated) 
      { 
       ListOfAcceptedUsers.Add(aUser); 
      } 
     } 

     //check new list instead of old one 
     if (ListOfAcceptedUsers.Count == 0 && isUserAvailable) 
     { 
      DeactivatedUserMessage(); 
      return; 
     } 

    } 
+0

Благодаря 4 ответа. Могу ли вы предложить модификацию в существующем коде .. – GethuJohn

+0

: s Я добавил модификацию, есть ли дополнительная модификация, или вы прокомментировали ее до конца моего редактирования. – Nealv

+0

Большое спасибо Nealv ... – GethuJohn

17

Вы не можете изменять коллекцию, пока вы итерацию над ней с foreach цикла. Типичные варианты:

  • Используйте for петлю вместо
  • Создайте отдельную коллекцию предметов, которые вы хотите, чтобы действовать дальше, то перебрать что.

Пример второго подхода:

List<EduvisionUser> usersToRemove = new List<EduvisionUser>(); 
foreach (EduvisionUser aUser in users) --->***Exception thrown in this line*** 
{ 
    isUserAvailable = true; 
    if(!aUser.Activated) 
    { 
     usersToRemove.Add(aUser); 
    } 
} 
foreach (EduvisionUser userToRemove in usersToRemove) 
{ 
    users.Remove(userToRemove); 
} 

Другой вариант, если вы используете List<T> является использование List<T>.RemoveAll:

isUserAvailable = users.Count > 0; 
users.RemoveAll(user => !user.Activated); 
+0

Насколько я ненавижу, чтобы продвигать кого-то с 200 000 повторений, +1. Я не использую RemoveAll столько, сколько мог. –

+1

@ Dave: Если это какое-то утешение, это не похоже на то, что upvote увеличил мой rep :) –

+0

Большое спасибо Jon Skeet – GethuJohn

0

вы можете сделать это следующим образом. Использовать вместо foreach

for(int i =0; i< users.Count; i++) --->***Exception thrown in this line*** 
{ 
    EduvisionUser aUser = users[i]; 
    isUserAvailable = true; 
    if(!aUser.Activated) 
    { 
    users.Remove(aUser); 
    i--; 
    } 
} 
0

Вы не можете изменить коллекцию при перечислении. Вместо удаления выберите только то, что вам нужно, и оставить сборщик мусора позаботится об остальном:

users = users.Where(x => x.Activated); 

или даже лучше, выбрать только то, что вам нужно из хранилища:

users = UserRespository.GetUserName(txtEmailID.Text).Where(x => x.Activated); 
+0

В большинстве случаев этот тип можно использовать, очень читаемый, меньше кода. Я использую это все время, если только мне не нужно выполнять функции в выражении лямбды. – Nealv

+0

Спасибо большое Дарин Димитров ... – GethuJohn

0

Моя цель состоит в том, чтобы удалите WorkCalendar из WorkCalendar, но при выборе Wc, в котором WorkHour выбрал исключение, подобное этому: «Коллекция была изменена, операция перечисления не может выполняться». Есть идеи? спасибо за помощь

Удалить метод:

попробовать {

  if (!this.DataWorkspace.ApplicationData.WorkCalendars.CanDelete) 
      { 
       this.ShowMessageBox("", "", MessageBoxOption.Ok); 
       return; 
      } 

      if (this.WorkCalendars.SelectedItem != null) 
      { 
       if ((this.WorkCalendars.SelectedItem.FindCalendarWPs.Count() > 0) || (this.WorkCalendars.SelectedItem.FindCalendarWPs1.Count() > 0)) 
       { 
        Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke 
     (() => 
     { 
      RadWindow.Alert(" "); 
     }); 
        return; 
       } 
       var y = DataWorkspace.ApplicationData.WorkCalendarDays.Where(w => w.WorkCalendar.Id == WorkCalendars.SelectedItem.Id).Execute().AsEnumerable(); 

       foreach (var item in y) 
       { 
        if(item.WorkingHoursCollection != null && item.WorkingHoursCollection.Count() > 0) 
         foreach (var WH in item.WorkingHoursCollection) 
         { 
          WH.Delete(); 
         } 
        item.Delete(); 

       } 
       if (this.WorkCalendars.SelectedItem == this.DataWorkspace.ApplicationData.WorkCalendars.Where(U => U.Id == this.WorkCalendars.SelectedItem.Id).SingleOrDefault()) 
       { 
        Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke 
     (() => 
     { 
      RadWindow.Alert(" "); 
     }); 
        return; 
       } 

       this.WorkCalendars.SelectedItem.Delete(); 
       this.Save(); 
      } 

     } 
     catch (Exception ex) 
     { 
      Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke 
      (() => 
      { 
       var msg = new LightSwitchApplication.Presentation.GeneralViews.ExceptionMessage(); 
       msg.DataContext = ex; 
       msg.ShowDialog(); 
      }); 
     } 
+0

Добро пожаловать в переполнение стека! Если у вас есть другой вопрос, обратитесь к нему, нажав кнопку [Ask Question] (http://stackoverflow.com/questions/ask). – Taryn