Mi sembra che molti dei metodi di estensione su IList<T>
siano applicabili a IEnumerable<T>
, ad esempio FindAll
e RemoveAll
.Perché IEnumerable <T> ha metodi FindAll o RemoveAll?
Qualcuno può spiegare il motivo per cui non ci sono?
Mi sembra che molti dei metodi di estensione su IList<T>
siano applicabili a IEnumerable<T>
, ad esempio FindAll
e RemoveAll
.Perché IEnumerable <T> ha metodi FindAll o RemoveAll?
Qualcuno può spiegare il motivo per cui non ci sono?
RemoveAll
non ha senso poiché non c'è Remove
ecc su tale API - tuttavia ci è un FindAll
da 3,5 in poi - ma è noto come Where
:
IEnumerable<Foo> source = ...
var filtered = source.Where(x => x.IsActive && x.Id = 25);
che è equivalente a:
IEnumerable<Foo> source = ...
var filtered = from x in source
where x.IsActive && x.Id == 25
select x;
Per RemoveAll
non è applicabile perché IEnumerable
IEnumerable è di sola lettura. Per FindAll
, vedere la risposta di Marc.
Tutto IEnumerable
fa specificare che esiste una raccolta che può essere enumerata o ripetuta. Non specifica nemmeno che la collezione possa essere ripetuta più volte, figuriamoci manipolata. Pertanto, qualsiasi metodo che manipola la raccolta non ha senso. Metodi come FindAll
avrebbero comunque senso.
Enumerabile non implica l'esistenza di una raccolta sottostante, quindi non è possibile sapere se è possibile rimuovere o meno qualcosa. Se è una raccolta sottostante, non si sa se supporta un'operazione di rimozione.
Ecco un metodo di esempio che elenca i numeri dispari. Se potessi "rimuovere" 7 da enumerabile, cosa accadrebbe? Da dove verrebbe rimosso?
public IEnumerable<int> GetOddPositiveNumbers()
{
int i = 0;
while (true)
{
yield return 2*(i++)+1;
}
}
Che cosa si potrebbe essere alla ricerca di è Where
e Except
che permette di filtro l'enumerabile.
+1 per l'esempio. – aboveyou00
Per essere giusti, qualcosa come IEnumerable<T>.RemoveAll
può davvero avere senso se quello che effettivamente si desidera è una versione a lunghezza zero di una raccolta particolare. Chiamarlo RemoveAll
non ha senso dal momento che nessuna implementazione del metodo IEnumerable<T>
dovrebbe modificare una raccolta.
Quindi nel mio caso a volte uso un metodo di estensione personalizzato che chiamo Nil
.
static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
yield break;
}
Quanto FindAll
come Marc già sottolineato è chiamato semplicemente Where
.
Grazie per la spiegazione, vedo più della foto ora, ma posso seguire due domande correlate: (1) perché Lista implementa FindAll e Where, assumendo che siano gli stessi: (2) Perché ICollection non implementa RemoveAll poiché implementa Remove? Grazie Andy –
Andy
@Andy Non penso ci sia un motivo per questo, ma puoi scrivere un metodo di estensione da solo, guarda la mia risposta. –
@'Andy 'Elenco' ottiene un 'dove' perché implementa' IEnumerable '.Re 'ICollection': perché non è una buona idea aggiungere metodi addizionali alle interfacce, TUTTAVIA, sarebbe perfettamente possibile implementarlo usando un metodo di estensione sull'interfaccia, –