2013-01-03 8 views
25

Ho una raccolta popup.Desidero rimuovere un elemento da una collezione IEnumerable <T>

Voglio rimuovere un elemento da esso, come posso fare questo?

foreach(var u in users) 
{ 
    if(u.userId = 1123) 
    { 
    // remove! 
    } 
} 

So che il vostro non supponiamo di rimuovere durante il ciclo, quindi non mi dispiace sia la creazione di una nuova collezione o di rimuoverlo dopo.

Ma non so come rimuovere un oggetto, tipo di perso per qualche motivo su questo!

alternativa che io sono confuso su anche, come posso creare una nuova collezione come:

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

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

Come posso aggiungere alla collezione?

risposta

0

Non è possibile. IEnumerable<T> può essere solo iterato.

Nel tuo secondo esempio, è possibile rimuovere dalla collezione originale di iterazione di una copia di esso

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

non è possibile rimuovere un elemento da un oggetto IEnumerable, può essere enumerato solo. Come descritto qui: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

Devi usare un ICollection se si desidera aggiungere e rimuovere elementi, forse si può provare a lanciare il vostro IEnumerable, questo sarà fuori rotta funziona solo se l'oggetto sottostante implementa ICollection.

Vedi qui per ulteriori informazioni su ICollection.
http://msdn.microsoft.com/en-us/library/92t2ye13.aspx

È possibile fuori rotta basta creare una nuova lista dal IEnumerable, come ha sottolineato lante, ma questo potrebbe essere "sub ottimale", a seconda del caso d'uso effettivo fuori rotta.
ICollection è probabilmente la strada da percorrere.

4

Provare a trasformare lo IEnumerable in un List. Da questo momento in poi sarai in grado di utilizzare il metodo diper rimuovere gli elementi.

farla passare come un parametro al metodo Remove utilizzando Linq è possibile ottenere l'oggetto con i seguenti metodi:

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

Il codice è il seguente:

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

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

// Finished 
+0

ma posso assegnarlo a qualcosa che si aspetta un afterwords IEnumerable? devo riavviarlo all'inizio? – loyalflow

+0

@ user1361315 ovviamente, List implementa IEnumerable, quindi puoi effettivamente assegnarlo a un IEnumerable – dutzu

28

Non rimuovere bu t creando una nuova matrice senza tale elemento con LINQ:

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

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

Stai creando un nuovo elenco in entrambi i casi. Il primo esempio sovrascrive il riferimento. –

+0

sì, quindi? non funziona per te? – lante

+3

La tua terminologia non è corretta. Non stai rimuovendo un elemento dall'elenco, in entrambi gli esempi crei un nuovo elenco e il vecchio elenco rimane inalterato. Stai semplicemente sovrascrivendo il riferimento nel tuo primo esempio, in quanto affermare che risulta in un 'remove' non corretto. Dovresti aggiornare la tua domanda per chiarirlo. –

0

L'interfaccia IEnumerable è proprio questo, enumerable - non fornisce alcun metodo per Add o Remove o modificare l'elenco affatto.

L'interfaccia solo fornisce un modo per iterare su alcune voci - la maggior parte delle implementazioni che richiedono l'enumerazione implementerà IEnumerable come List<T>

Perché non basta utilizzare il codice senza il cast implicito a 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

Devo modificarlo, quindi passarlo a qualcosa che si aspetta un ienumerable. – loyalflow

+0

Quindi modificarlo e passarlo - non c'è motivo per cui non si possa passare un 'Elenco ' a un metodo che si aspetta un 'IEnumerable ' poiché 'Elenco ' deriva da 'IEnumerable '. Non penso nemmeno che tu abbia bisogno di un cast a causa delle regole di covarianza. – Charleh

Problemi correlati