2013-03-27 21 views
7

Nie mogę usunąć elementu z listy IEnumerable, ale ta lista jest odniesieniem do listy, prywatnym atrybutem innej klasy. Jeśli wstawię personsCollection.Remove(theElement) w tej samej klasie (Menedżer klasy), działa idealnie, ale muszę usunąć element, ponieważ druga klasa (klasa ManagerDelete). Jak mogę to zrobić? Dzięki.Usuwanie elementu z ogólnej listy

class Other 
{ 
    //Some code 
    public IEnumerable<Person> SearchByPhone (string value) 
    { 
     return from person in personCollection 
       where person.SPhone == value 
       select person; 
    } 
} 

class ManagerDelete 
{ 
//Some code 
IEnumerable<Person> auxList= SearchByPhone (value); 
//I have a method for delete here 
} 

class Manager 
{ 
//Some code 
private List<Person> personsCollection = new List<Person>(); 
} 

Odpowiedz

12

nie można usunąć z IEnumerable<T> trzeba zrobić to od rodzaju IList<T> dodać/usunąć elementy bezpośrednio od niego.

+1

'ILIST' nie jest konieczne," ICollection "wystarczy. – svick

1

Możesz rzucić IEnumerable do IList. To zadziała, jeśli IEnumerable jest naprawdę List. Jest to jednak zły projekt. Jeśli chcesz usunąć elementy, należy ujawnić listę jako IList, a nie IEnumerable.

1

An IEnumerable jest dosłownie interfejsem mówiącym, że mam tę kolekcję, możesz ją powtórzyć.

Jeśli spojrzeć na rzeczywistych szczegółów interfejsu IEnumerable, że nie zawiera on dużo, tylko sposób, aby umożliwić rozmówcy iteracyjne nad nim:

http://msdn.microsoft.com/en-gb/library/9eekhta0.aspx

powód dlaczego List typy pozwala na ich usunięcie, jest on zbudowany na górze interfejsu IEnumerable, co zapewnia większą funkcjonalność. Ma on reprezentować zbiór obiektów, którymi możesz manipulować. Podczas gdy IEnumerable po prostu nie jest przeznaczony do tego.

Sposób Remove faktycznie wywodzi się z podstawowej ICollection interfejs List implementuje również:

http://msdn.microsoft.com/en-gb/library/bye7h94w.aspx

3

Darren ma rację. bez potrzeby konwersji na liście można zrobić:

personCollection = personCollection.Except(SearchByPhone(value)); 

w ManagerDelete.

+0

+1 za używanie Z wyjątkiem jednak należy uważać, że poprzez zastąpienie 'personCollection' wszelkie inne obiekty, które mają odniesienie do' personCollection' będą nadal wskazywały na stary, można to obejść za pomocą [BindingSource] (http: //msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx) lub podobna klasa działająca jako pośrednik. –

4

Musisz zrozumieć, co pozwala interfejs IEnumerable.

Wymieniono poniżej listę interfejsów, z których należy korzystać według projektu, w razie potrzeby w różnych okolicznościach. W twoim przykładzie IList jest to, czego będziesz potrzebować.

  • ICollection definiuje ogólne właściwości (na przykład wielkości, wyliczenie, i bezpieczeństwa gwintu) dla wszystkich nierodzajową typów odpadów.

  • ICloneable Pozwala obiektowi wykonawczemu zwrócić kopię samego siebie do osoby dzwoniącej.

  • IDictionary Umożliwia nie-rodzajowemu obiektowi kolekcji reprezentowanie jego zawartości za pomocą par klucz/wartość.

  • IEnumerable Zwraca obiekt implementujący interfejs IEnumerator (patrz następny wpis w tabeli).

  • IEnumerator Włącza iterację kolekcji przedmiotów w foreach.

  • ILIST Udostępnia funkcje dodawania, usuwania i indeksowania elementów na kolejnej liście obiektów.

+0

Nie zapominaj, że istnieje różnica między 'IList' i' IList ',' List' może implementować 'IList', ale inne listy z silnym typowaniem mogą nie być. –

2

Można użyć ToList do konwersji IEnumerable Do List a następnie można wyjąć rzeczy z nim.

var auxList= SearchByPhone (value).ToList(); 
auxList.Remove(something); 
1

Oprócz innych odpowiedzi: wybór struktury danych nie wydaje się być adekwatny. Jeśli naprawdę planujesz usunąć elementy z pojemnika, Twój kontener nie może być an IEnumerable<> w pierwszej kolejności!

Rozważmy następujące opcje:

  • przełącznik z IEnumerable<> do ICollection<>;
  • wymień usunięcie z filtrowaniem (.Where()) i uzyskaj oddzielne filtrowane IEnumerable<>.
Powiązane problemy