LINQ, attuato attraverso i metodi di estensione all'interno della classe Enumerable
, deduce esecuzione differita:
metodi che vengono utilizzati in una query che restituisce una sequenza di valori non consumare i dati di destinazione finché la query oggetto è elencato. Questo è noto come esecuzione differita.
Cast<T>
non crea immediatamente un nuovo elenco, ma memorizza tutte le informazioni necessarie per eseguire l'azione. L'elenco viene enumerato solo quando richiesto (ad esempio, tramite una dichiarazione foreach
).
Nel tuo caso, se semplicemente intenzione di iterare la sequenza, si dovrebbe considerare attaccare all'interfaccia IEnumerable<T>
, che è il tipo di ritorno dichiarato di Cast<T>
:
IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
foreach (SomethingElse se in second)
{
// ...
}
Questa è efficiente, dal momento che solo esegue il cast come ogni elemento viene iterato.
Se sei convinto che si desidera una nuova lista da creare immediatamente, utilizzare ToList
:
List<SomethingElse> second = first.Cast<SomethingElse>().ToList();
Edit: Risposta a punto pubblicato in commento:
Dipende da cosa si intende da "una lista che può essere modificata". Esistono diversi operatori di query LINQ che consentono di modificare ulteriormente la definizione della query. Ad esempio, se si desidera rimuovere tutti SomethingElse
elementi i cui IsDeleted
proprietà è true
, è possibile utilizzare l'Where
dell'operatore:
IEnumerable<SomethingElse> second = first.Cast<SomethingElse>();
second = second.Where(element => !element.IsDeleted);
Se si desidera aggiungere una sequenza di nuovi elementi, è possibile utilizzare l'operatore Concat
:
second = second.Concat(anotherCollectionOfSomethingElse);
Se si desidera ordinare la sequenza in ordine crescente di ID
, utilizzare il OrderBy
dell'operatore:
second = second.OrderBy(element => element.ID);
Ogni volta, stiamo applicando un operatore di query sopra l'ex definizione della nostra query e assegnare il nuovo (composito) query per la nostra variabile second
. LINQ memorizzerebbe tutti i tuoi operatori nella definizione della query. Poi, quando la sequenza è effettivamente enumerato (ad esempio, attraverso un foreach
o ToList
), si darebbe il risultato composito della sequenza, con tutti gli operatori di query applicati in ordine.
Come in tutti i casi di esecuzione differita/valutazione pigra, fare attenzione a non esagerare con questo. Se, per esempio, si sta andando ad applicare un operatore Where
che ridurrà la dimensione della sequenza drasticamente, potrebbe avere senso per eseguire la query con entusiasmo e memorizzare la lista numerata, invece.
correlati? http://stackoverflow.com/questions/1266014/c-sharp-casting-a-listobjbase-as-listobj – eldarerathis
Eventuale duplicato di http://stackoverflow.com/questions/7955890/how-to-cast-listclassb-to -listclassa-when-classb-inherits-from-classa – dash
Funzionerebbe? Elenca secondo = first.Select (o => (SomethingElse) o) .ToList(); –
asmo