2013-11-20 11 views
10

Quando guardo la lista popolata con un singolo elemento nel debugger il suo campo _items contiene 4 elementi. Puoi spiegare il comportamento?L'elenco mostra 4 elementi nel debugger anche se riempito con esattamente un elemento

Ho scoperto che durante il debug dell'applicazione console per informazioni su Distinct e ToList e il risultato mi confonde. Codice:

List<int> nums = new List<int>() { 6, 6, 6, 6, 6, 6, 6, 6 }; 
List<int> distinctNums = nums.Distinct().ToList(); 
int[] distinctNums2 = nums.Distinct().ToArray(); 
  • distinctNums ha 4 elementi in _items: (6, 0, 0, 0) che è chiaramente sbagliata.
  • distinctNums2 ha 1 elemento (6) che è corretto.
+2

Entrambi restituiscono un singolo elemento nell'elenco, Come stai controllando il risultato? – Habib

+1

Ho aggiornato in modo significativo il tuo post per riflettere il coinvolgimento del debugger. Sentiti libero di modificare se non ti piace. –

risposta

12

Ciò creerà l'elenco distinctNums che contiene solo un elemento, proprio come dovrebbe. Tuttavia, gli elenchi in .NET sono supportati da un array che viene ridimensionato automaticamente man mano che vengono aggiunti elementi. Questo array inizia con una dimensione di 4, quindi l'array interno sarebbe [4, 0, 0, 0] se lo si verifica tramite riflessione o in un debugger.

Ma se controlli, troverai distinctNums.Count == 1. Confronta le proprietà Count e Capacity.

+1

+1 per una bella ripartizione degli interni! –

+0

sembra che l'OP abbia utilizzato 'Capacità' per verificare il numero di articoli? Così terribile. –

+1

+1 @KingKing - più probabile OP ha semplicemente fatto clic su "+" fino a vedere il primo campo effettivo (prova a guardare una lista in VS editor mentre esegui il debug e fai clic su "Visualizzazione raw") –

3

Entrambi distinctNums e distinctNums2 contengono solo un oggetto.

L'elenco con quattro elementi visualizzati nel debugger è solo la matrice che supporta lo List<int>. Si può vedere che il suo Count è 1 e che se si itera l'elenco, si restituisce solo un singolo 6.

1

List<T> è un'astrazione sopra a T[] (una matrice standard). La dimensione dell'array non ha importanza. Quando si assegna uno List<T> a un elemento, il compilatore non alloca lo new T[1], ma offre spazio per la crescita (deve ridistribuire un nuovo array e copiare gli elementi quando si supera quello originale, un'operazione relativamente costosa). Count ti dà la lunghezza degli elenchi e se la chiami su quell'elenco otterrai 1. Gli altri tre indici hanno il valore predefinito di zero e non fanno parte del tuo elenco, fanno parte dell'array sottostante. Non sono rilevanti. Se si è tentato di fare myList[3] si potrebbe ancora ottenere un'eccezione, non sarebbe solo tornare che 0.

Per portare questo torna alla domanda iniziale, in entrambi i casi Distinct ritorna e IEnumberable<int> con una sola voce. Quando si chiama ToList si assegna un nuovo elenco, il conteggio è 1, la struttura dati sottostante è un int[] con una lunghezza iniziale di 4. Se si aggiungessero più elementi, esso aumenterebbe. Nel secondo esempio si chiama ToArray in modo che assegnasse un nuovo int[1] e restituisca il riferimento ad esso.