2012-01-04 9 views
6

Se abbiamo la seguente dichiarazione di variabile:Perché l'inserimento dell'elenco fallisce quando viene fornita una dimensione sufficiente per la costruzione?

List<int> list = new List(5); 

Perché questo:

list.insert(2, 3); 

non con il seguente errore:

Index must be within the bounds of the List. 

Qual è il punto di fornire la dimensione iniziale?

+4

Non è possibile inserire nella posizione 2, se le posizioni 0 e 1 non sono ancora riempiti –

+0

Come sottolineato correttamente, la capacità non è la stessa dimensione . Scrivi il Conteggio alla console prima di chiamare Inserisci, l'elenco ha meno di 3 elementi, quindi l'inserimento di un nuovo valore nella 3a posizione non riesce. –

risposta

8

Tutte le dimensioni iniziali corrispondono a provide a hint to the implementation to have at least a given capacity. Non crea una lista piena di voci di default N; sottolineatura mia:

Initializes a new instance of the List<T> class that is empty and has the specified initial capacity.

Se si continua attraverso la voce di MSDN alla sezione Osservazioni, troverete il motivo per cui è previsto questo sovraccarico costruttore (di nuovo, sottolineatura mia):

The capacity of a List<T> is the number of elements that the List<T> can hold. As elements are added to a List<T> , the capacity is automatically increased as required by reallocating the internal array.

If the size of the collection can be estimated, specifying the initial capacity eliminates the need to perform a number of resizing operations while adding elements to the List<T> .

Insomma List<T>.Count è non uguale a List<T>.Capacity ("Se il conteggio supera la capacità aggiungendo elementi, la capacità aumenta ...").

Si riceve l'eccezione perché la lista unica logicamente contiene gli elementi aggiunti, cambiando la capacità non cambia il numero di elementi logicamente memorizzati. Se si dovesse impostare List<T>.Capacity a meno di List<T>.Count possiamo verificare questo comportamento andando nella direzione opposta:

Unhandled Exception: System.ArgumentOutOfRangeException: capacity was less than 
the current size. 
Parameter name: value 
    at System.Collections.Generic.List`1.set_Capacity(Int32 value) 

Per creare forse il comportamento che stai cercando:

public static List<T> CreateDefaultList<T>(int entries) 
{ 
    return new List<T>(new T[entries]); 
} 
+0

Quindi a cosa serve questo suggerimento se non creare un backing store iniziale? – Erix

+0

L''Elenco ' non * ha * per usare un array per un backing store, potrebbe usare un 'LinkedList ' o qualche altra implementazione. Tutto quello che stai facendo è dire di * aspettarti * 'N 'voci nella speranza che l'impatto sulle prestazioni dell'espansione della lista tenga in considerazione che molte voci saranno trascurabili. – user7116

+0

Significa semplicemente che può ricevere 5 elementi prima che l'oggetto List debba crescere. È un'ottimizzazione delle prestazioni. – Tormod

0

Perché inserto presuppone che il la lista ha in effetti già molti articoli inseriti - la capacità non è la stessa cosa della dimensione. L'inizializzazione dell'elenco con una determinata capacità imposta semplicemente la dimensione dell'array interno: si tratta di un'ottimizzazione per impedire il ridimensionamento dell'array quando si conosce il numero di elementi che si stanno inserendo.

0

Il costruttore List (int) specifica la capacità iniziale dell'elenco. Non specifica il numero di elementi iniziali. Al momento della costruzione una lista è vuota quindi, qualsiasi inserimento può essere fatto solo all'indice 0.

2

La dimensione nel costruttore indica quanto allocare per l'array di sfondo - è ancora, tuttavia, vuoto (solo: vuoto con una certa quantità di spazio iniziale).

È possibile inserirlo nella parte utilizzata dell'elenco o alla fine.

2

Internamente un List(T) viene implementato utilizzando una matrice in background. Quando si inizializza l'elenco in questo modo, si imposta semplicemente la dimensione dell'array sottostante che viene ridimensionato man mano che l'elenco cresce. Quindi, stai inizializzando la capacità iniziale. Ciò non significa che la tua lista abbia tanti elementi.

Aggiungete elementi alla lista inizializzandola prima e aggiungendovi elementi con .Add(item).

0

La dimensione iniziale viene utilizzata per indicare la dimensione dell'array interno, inizialmente.

Quando si inseriscono elementi in un elenco, questi vengono archiviati in un array. Quando l'array è pieno, crea una nuova matrice di dimensioni doppie e copia tutti gli elementi. Se hai un'idea che stai per inserire 5000 elementi, vorresti specificare quel suggerimento in modo che non finisca con il ridimensionamento/copia di molti array.

La dimensione iniziale è non indicare che ci sono alcuni elementi nella lista però.

0

Questo perché il numero intero specificato nel costruttore è la quantità che l'elenco può contenere. Quando gli articoli vengono aggiunti, l'elenco viene automaticamente aumentato. Il ridimensionamento viene evitato quando si specifica una capacità iniziale che corrisponde al numero di elementi che si desidera aggiungere.

Tuttavia, è ancora necessario utilizzare il metodo Aggiungi per aggiungere nuovi elementi.

Vedere la remarks section in the documentation

Problemi correlati