2010-06-07 9 views
5

Il codice che sto scrivendo riceve un ArrayList dal codice non gestito e questo ArrayList conterrà sempre uno o più oggetti di tipo Grid_Heading_Blk. Ho preso in considerazione la possibilità di cambiare questo ArrayList in un Elenco generico, ma non sono sicuro se l'operazione di conversione sarà così costosa da annullare i vantaggi del lavorare con la lista generica. Attualmente sto solo eseguendo un'operazione foreach (Grid_Heading_Blk in myArrayList) per lavorare con il contenuto di ArrayList dopo aver passato ArrayList alla classe che lo userà.La conversione di questo ArrayList in un Elenco generico è efficiente?

Devo convertire ArrayList in un elenco tipizzato generico? E se sì, qual è il modo più efficace per farlo?

risposta

2

Ecco un modo efficace per creare un elenco generico da un ArrayList.

List<Grid_Heading_Blk> myList = new List<Grid_Heading_Blk>(source.Count); 
myList.AddRange(source.OfType<Grid_Heading_Blk>()); 

Chiamando il costruttore che accetta un int, il supporto di memorizzazione viene assegnato una volta sola.

Come sempre, è necessario misurare le prestazioni utilizzando qualsiasi strumento che si utilizza normalmente.

+1

Grazie, tutti. Molte buone risposte qui. Mentre la performance/efficienza è certamente un problema chiave, potrei aver sottovalutato la leggibilità fornita da una struttura tipizzata. Se qualcun altro sta alla fine mantenendo il mio codice, voglio che sia il più chiaro possibile di quello che sto facendo. – Greg

1

La penalità maggiore che si ha utilizzando ArrayLists è il pugilato.

con i generici si ottiene:
1. compilazione di sicurezza tempo
2. generici estensioni
3. Rimuovere questa limitazione di avere tutto nella lista convertito al tipo di oggetto.

Questi sono i vantaggi che si ottengono nel loro utilizzo. Sono vantaggiosi, ma se devi reinserire il generico da ArrayList, potrebbe non valere la pena farlo, specialmente se stai semplicemente scorrendo l'elenco per ottenere gli oggetti.

0

"Efficient" non è né-né proprietà. È relativo, proprio come un grosso topo non è probabilmente più grande di un piccolo elefante.

Dipende da cos'altro si sta facendo.

vostro chilometraggio può variare, ma nella mia esperienza, mentre ArrayList può essere "più lento" rispetto List<T>, non ho mai fatto in modo poco altro che era in alcun modo evidente.

Detto questo, è bello avere il compilatore che esegue il controllo dei tipi per me, ed è bello non dover trasmettere le cose.

2

Io uso spesso questa lista di controllo per valutare le domande come la tua:

  1. Rendere più corretto
  2. in modo chiaro
  3. Ne fanno conciso
  4. rendono efficiente

List<Grid_Heading_Blk> è lontano più intenzionale-rivelando di ArrayList. Così, senza nemmeno considerare l'efficienza, c'è già una grande vittoria per voce 2.

Per convertire un ArrayList ad un List<>, si deve iterare il ArrayList una volta e gettato ogni elemento. Lo foreach sta eseguendo un cast implicito, quindi l'overhead è solo nell'iterazione extra.

L'iterazione di una sequenza due volte porta la prestazione da O(n) a O(2n), che è ancora O(n) (grandezza, non valore, è ciò che conta per le prestazioni). Pertanto, puoi considerare il cambiamento benigno.

Tuttavia, se letteralmente tutto che state facendo è in esecuzione il foreach, si deve solo usare ArrayList direttamente - a cambiarlo con List<> si acquista il potere non più espressivo.

0

Se gli oggetti provengono da codice non gestito e non è necessario aggiungere o rimuovere oggetti, un array di Grid_Heading_Blk potrebbe essere più efficiente di un elenco. Se riesci a farla franca con un array, usare un ciclo for potrebbe essere leggermente più veloce di foreach.

2

Perché è necessario convertire lo ArrayList? Per essere onesti, il tuo ciclo di foreach sembra fare il trucco. Sì, come dice Kevin sopra l'unica penalità che pagheresti è unboxing - ma così com'è, è un codice piuttosto semplice e probabilmente non hai abbastanza titoli di griglia per pagare un vero colpo di performance.

Ma se è necessario convertirlo direi, piuttosto che scrivere il proprio ciclo for per convertire il tipo generico elenco, potrebbe essere meglio per utilizzare il costruttore che prende IEnumerable tipo (qualcosa ArrayList dovrebbe implementare già.)

List<Grid_Heading_Blk> heading = new List<Grid_Heading_Blk>(arrayList);