2016-09-10 10 views
1

Imagine Ich habe eine Methode bekam die Liste der Werttypen gibt:C# Speicherverwaltung Werttyp innerhalb Liste

static List<SomeValueType> AllocateList() 
{ 
    List<SomeValueType> lst = new List<SomeValueType>(); 
    for (int i = 0; i < 1000000; i++) 
    { 
     lst.Add(new SomeValueType("....", "...")); 
    } 
    return lst; 
} 

ich einige Missverständnisse haben. Sobald wir diese Methode aufgerufen haben, wird ref zur Liste der Werttypen zurückgegeben, und der Stack-Frame wird zerstört. Aber was ist mit SomeValueType Artikel. Wird es in den Stack-Frame der Aufrufer-Methode kopiert oder in eine Box oder in eine andere Form?

Wenn Listenelemente in den Heap kopiert werden, was ist der Unterschied zwischen Boxen und Werttypen kopieren, um Speicher aufzulisten?

Antwort

1

Ein List<T> ist ein Referenztyp. Da es das einkapselnde Objekt ist, wird SomeValueType auf dem Heap zugeordnet, nicht Stapel. Genauer gesagt, nach der Zuweisung von SomeValueType auf dem Stapel, wird es zum zugrunde liegenden Speicher des List<T>, der auf dem Heap ist, aufgehoben. Somit wird es nicht notwendig sein, das Stapelbild zu kopieren oder ähnliches, und es wird auch kein Boxen mehr nötig sein.

Werttypen werden als Implementierungsdetail zugeordnet Stapel, sie auf dem Heap für Boxen ohne Notwendigkeit zugeordnet werden können, die gleiche Art und Weise ein int[] auf dem Heap zugewiesen.

+0

Auf diese Weise, was ist der Unterschied zwischen Boxen und Kopieren zu einem Listenspeicher? – xalz

+1

@xalz Das Kopieren erfordert kein zusätzliches Objekt, das auf dem Heap zugeordnet werden soll, um den Werttyp zu kapseln, es wird wie im Heap kopiert. –

1

SomeValueType Elemente werden nach Wert in den Speicher innerhalb des Objekts List<SomeValueType> kopiert. Listenimplementierung enthält ein generisches Array von Elementen. Hier werden SomeValueType gespeichert.

Die Liste selbst ist ein Referenztyp, daher wird lst als Referenz zurückgegeben.

Wenn der Anrufer die Liste zugreift, sagen wir, wie folgt aus:

SomeValueType item5 = allocatedList[5]; 

dann würde der Wert aus der Liste des Index 5 in Anrufers Stapelrahmen kopiert werden.