2013-01-03 16 views
25

Mam zlicytowaną kolekcję IEnumerable<User>.Chcesz usunąć element z kolekcji IEnumerable <T>

Chcę usunąć z niego przedmiot, jak mogę to zrobić?

Wiem, że nie należy usuwać podczas pętli, więc nie mam nic przeciwko tworzeniu nowej kolekcji lub usuwaniu jej po.

Ale nie wiem, jak usunąć przedmiot, który z jakiegoś powodu został utracony!

Alternatywnie której jestem zdezorientowany na również, w jaki sposób można utworzyć nową kolekcję takich jak:

IEnumerable<User> modifiedUsers = new List<User>(); 

foreach(var u in users) 
{ 
    if(u.userId != 1233) 
    { 
     modifiedUsers.add ?????? 
    } 
} 

Jak mogę dodać do kolekcji?

Odpowiedz

0

Nie możesz. IEnumerable<T> może być iterowane.

W drugim przykładzie, można usunąć z oryginalnej kolekcji przez iteracji nad kopią nim

foreach(var u in users.ToArray()) // ToArray creates a copy 
{ 
    if(u.userId != 1233) 
    { 
     users.Remove(u); 
    } 
} 
8

nie można usunąć element z IEnumerable, to może być wyliczane tylko. Jak opisano tutaj: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

Musisz użyć kolekcji ICollection, jeśli chcesz, aby dodawać i usuwać elementy, może można spróbować i oddawania IEnumerable, to będzie się oczywiście tylko działać, jeśli bazowy obiekt implementuje kolekcji ICollection.

Zobacz tutaj więcej o ICollection.
http://msdn.microsoft.com/en-us/library/92t2ye13.aspx

Można się oczywiście tylko utworzyć nową listę z Twojego IEnumerable, jak podkreślił Lante, ale może to być „sub optymalne”, w zależności od rzeczywistego przypadku użycia z kursu.
ICollection to prawdopodobnie droga.

4

Spróbuj zmienić IEnumerable w List. Od tego momentu będziesz mógł używać metody List do usuwania elementów.

Aby przekazać go jako param metody Remove użyciu LINQ można uzyskać pozycję za pomocą następujących metod:

  • users.Single(x => x.userId == 1123)
  • users.First(x => x.userId == 1123)

Kod jest następujący:

users = users.ToList(); // Get IEnumerable as List 

users.Remove(users.First(x => x.userId == 1123)); // Remove item 

// Finished 
+0

ale mogę przypisać go do czegoś, co oczekuje IEnumerable Afterwords? czy muszę go ponownie uruchomić na początek? – loyalflow

+0

@ user1361315 Oczywiście, lista implementuje IEnumerable, więc możesz go przypisać do IEnumerable – dutzu

28

Nieusuwanie bu t tworząc nową tablicę bez tego elementu z LINQ:

// remove 
users = users.Where(u => u.userId != 123).ToList(); 

// new list 
var modified = users.Where(u => u.userId == 123).ToList(); 
+0

Tworzysz nową listę w obu przypadkach. Pierwszy przykład po prostu zastępuje odniesienie. –

+0

tak, więc? nie działa dla ciebie? – lante

+3

Twoja terminologia nie jest poprawna. Nie usuwasz elementu z listy, W obu przykładach tworzysz nową listę, a stara lista pozostaje niezmieniona. Po prostu zastępujesz referencję w swoim pierwszym przykładzie, ponieważ takie stwierdzenie, że powoduje, że 'remove' jest niepoprawne. Powinieneś zaktualizować swoje pytanie, aby to wyjaśnić. –

0

Interfejs IEnumerable jest tak, że wyliczalnych - nie dostarcza żadnych metod Add lub Remove lub zmodyfikowanie listy w ogóle.

Interfejs tylko zapewnia sposób iterację na niektóre elementy - większość wdrożeń, które wymagają wyliczanie wdroży IEnumerable takich jak List<T>

Dlaczego nie wystarczy użyć kodu bez niejawny oddanych do IEnumerable

// Treat this like a list, not an enumerable 
List<User> modifiedUsers = new List<User>(); 

foreach(var u in users) 
{ 
    if(u.userId != 1233) 
    { 
     // Use List<T>.Add 
     modifiedUsers.Add(u); 
    } 
} 
+0

Muszę go zmodyfikować, a następnie przekazać do czegoś, czego oczekuje się od niezliczonych. – loyalflow

+0

Następnie zmodyfikuj go i przekazuj - nie ma powodu, dla którego nie można przekazać "Listy " metodzie, która oczekuje "IEnumerable ", ponieważ 'Lista ' pochodzi od 'IEnumerable '. Nie sądzę, że potrzebujesz obsady z powodu reguł kowariancji. – Charleh

Powiązane problemy