Equivalente in C # del vettore C ++, con memoria contigua?


87

Qual è l'equivalente in C # del vettore C ++?

Sto cercando questa funzione:

Disporre di un array dinamico di memoria archiviata in modo contiguo che non abbia alcuna riduzione delle prestazioni per l'accesso rispetto agli array standard.

Stavo cercando e loro dicono .NET equivalent to the vector in C++ is the ArrayList, quindi:

ArrayList ha quella funzione di memoria contigua?


4
Il CLR non è sufficientemente vicino al metallo perché tu possa specificare (o addirittura aspettarti costantemente) come una struttura viene allocata in memoria?
Aphex

Risposte:


104

È possibile utilizzare a List<T>e quando Tè un tipo di valore, verrà allocato nella memoria contigua, il che non sarebbe il caso se Tfosse un tipo di riferimento.

Esempio:

List<int> integers = new List<int>();
integers.Add(1);
integers.Add(4);
integers.Add(7);

int someElement = integers[1];

2
@cMinor, la documentazione della List<T>classe contiene molti esempi ma ho aggiornato la mia risposta per includerne uno.
Darin Dimitrov

5
Non ho familiarità al 100% con il CLR, ma ha senso che anche se Tè un tipo di riferimento avrai comunque memoria contigua. È fondamentalmente una serie di puntatori ...
josaphatv

"il che non sarebbe il caso se T fosse un tipo di riferimento" - è altrettanto vero quanto per T[]... l'OP ha chiesto "nessuna penalizzazione delle prestazioni per l'accesso rispetto agli array standard", e lo List<T>fornisce. E se Tè un tipo di riferimento, è analogo a T*in C ++, quindi ottieni la stessa contiguità di C ++. Se si desidera che gli oggetti stessi siano contigui, ovviamente occorrono tipi di valore ... in entrambe le lingue. La differenza, ovviamente, è che in C ++ qualsiasi tipo può essere utilizzato come valore o ref, mentre in C # è una proprietà del tipo tramite la distinzione class / struct.
Jim Balter

Ho imparato qualcosa oggi. Ho pensato che List<T>sia sempre implementato internamente come elenco collegato. Quindi come si espande dinamicamente quando chiamiamo Add()? Qualcosa come il VB6 Redim Preserveche copiava l'intero array in una nuova posizione?
dotNET

@dotNet, List<T>crea internamente un piccolo array T[]. Gli elementi internamente vengono aggiunti all'array. Una volta completata la dimensione dell'array, viene creato un nuovo array doppia dimensione del precedente. I dati vengono copiati nel nuovo array più grande, il più piccolo viene eliminato e così via. Uno sviluppatore può dare un suggerimento per .NET per creare una vasta gamma interna abbastanza prima di riempire la List via del costruttore: new List<T>(expected_array_size).
Artru

16

utilizzare List<T>. Internamente utilizza array e gli array utilizzano memoria contigua.


2
Non del tutto vero. Se T è un tipo di riferimento, non ci sarà memoria contigua.
Matteo Mosca

2
@Matteo se guardi la fonte, c'è private T[] _items;quella usata per l'archiviazione back-end, tipo di riferimento o meno.
Bala R

13
Bene, lo so. Ma dimmi. Hai una lista <SomeClass>. I riferimenti alle istanze SomeClass verranno archiviati nella memoria contigua, ma non nelle istanze stesse. Come tipi di riferimento, saranno nell'heap e sicuramente saprai come funziona l'heap.
Matteo Mosca

@MatteoMosca che memorizza i riferimenti in modo contiguo rimuove almeno un livello di riferimento indiretto. Meglio di niente immagino.
Tim Seguine

7
@MatteoMosca L'OP ha chiesto "nessuna penalizzazione delle prestazioni per l'accesso rispetto agli array standard". Questo è vero per List <T> indipendentemente da cosa sia T, quindi tutti i tuoi commenti su questa pagina sono fuori luogo.
Jim Balter

16

Prima di tutto, stai lontano da Arraylisto Hashtable. Queste classi sono da considerarsi deprecate, a favore dei generici. Sono ancora nella lingua per scopi legacy.

Quello che stai cercando è la List<T>classe. Nota che se T è un tipo di valore avrai memoria contiguos, ma non se T è un tipo di riferimento, per ovvie ragioni.


15

C # ha molti tipi di riferimento. Anche se un contenitore memorizza i riferimenti in modo contiguo, gli oggetti stessi potrebbero essere sparsi nell'heap


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.