2014-07-01 4 views
6

Sto passando un lungo elenco di oggetti per fare alcune cose riguardo a detti oggetti nell'elenco.Il list.count esegue iteramente fisicamente l'elenco per contarlo o mantiene un puntatore

Durante la mia iterazione, rimuoverò alcuni oggetti dall'elenco in base a determinati criteri.

Una volta terminato, ho bisogno di aggiornare l'interfaccia utente per quanto riguarda il numero di oggetti nella mia lista. (Elenco di T).

DOMANDA:

Quando chiamo list.count, non .net realtà scorrere l'elenco per numero di esso, o lo fa memorizzare il conteggio come una proprietà/variabili?

Se .net continua a scorrere fisicamente nell'elenco, posso anche tenere un contatore sulla mia iterazione attraverso l'elenco e salvare il sovraccarico?

Grazie

+6

http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs – SLaks

risposta

7

List è implementato come una lista di array, e mantiene traccia del suo proprio formato, quindi invocando la proprietà .Count non richiede alcuna iterazione.

Se si chiama il metodo di estensione LINQ .Count(), questo sarà verificare se il sottostante IEnumerable<> implementa ICollection (che un List<> fa), e utilizzare la proprietà .Count su tale interfaccia, se possibile. Quindi questo non causerà alcuna iterazione.

Per inciso, ci sono altri problemi che si incontreranno se si tenta di rimuovere gli elementi dall'elenco mentre si scorre attraverso di esso. Non è chiaro come dovrebbe comportarsi l'iterazione quando si rimuovono elementi da sotto l'iteratore, quindi List<> s eviterà completamente questo problema lanciando un'eccezione se l'elenco è stato modificato da quando è stato creato il suo enumeratore.

+0

Qualsiasi collegamento, codice per il backup della dichiarazione? (So ​​che è vero) –

+0

@ L.B: Ci stavo lavorando, ma sembra che altre persone abbiano fornito quei collegamenti prima di me. – StriplingWarrior

+0

Ottenuto: * "Per prima cosa, inserisci una risposta veloce al segnaposto, quindi migliorala" * –

2

È possibile utilizzare un decompilatore, come ILSpy liberamente disponibile, per rispondere a queste domande. Se ti riferisci al tipo List<T>, quindi il getter Count comporta la semplice lettura di un campo:

public int Count 
{ 
    get { return this._size; } 
} 
1

Hai taggato la tua domanda sia con vb.net che con C#, quindi in risposta a "If.net fisicamente ri-scorre l'elenco, I possono altrettanto bene mantenere un contatore da solo un'iterazione attraverso l'elenco e salvare l'overhead?"

Se l'iterazione è con un For i = first To last allora VB.NET valuterà first e last quando entra nel ciclo:

Dim first As Integer = 1 
Dim last As Integer = 3 
For i = first To last 
    Console.Write(i.ToString() & " ") 
    last = -99 
Next 

uscite: 1 2 3

Se si esegue l'equivalente in C#, first e last sono valutati su ogni iterazione:

int first = 1; 
int last = 1; 
for (int i = first; i <= last; i++) 
{ 
    Console.Write(i.ToString() + " "); 
    last = -99; 
} 

uscite: 1

Se il Count() Funzione/proprietà è costoso da valutare e/o non si desidera che venga rivalutato ad ogni iterazione (per qualche altro motivo), quindi in C# potresti assegnarlo a una variabile temporanea.

Problemi correlati