2009-04-26 11 views
2

Juste pour vous assurer que je comprends des copies peu profondes correctement et que des types de référence, je ne suis pas la construction d'une énorme fuite de mémoire ici:Question sur tableau copie superficielle en C#

// Adds text to the beginning of the log RTB 
// Also keeps the log RTB trimmed to 100 lines 
var lines = new string[rtbLog.Lines.Length + 1]; 
lines[0] = "text"; 
Array.Copy(rtbLog.Lines, 0, lines, 1, rtbLog.Lines.Length); 

if (lines.Length > 100) 
{ 
    Array.Resize(ref lines, 100); 
} 

rtbLog.Lines = lines; 

Ce serait tout d'abord copier les refs aux chaînes dans rtbLog.Lines en lignes. Ensuite, il copiera les 100 premières références de lignes dans un nouveau tableau de chaînes. Cela signifie que le tableau référencé à l'origine par rtbLog.Lines, le tableau initialement référencé par des lignes (avant le redimensionnement), et enfin toutes les chaînes non contenues dans les lignes (après le redimensionnement), tous sont récupérés. (J'espère que cela a du sens)

Correct?

Répondre

1

La méthode Array.Resize est un peu impropre. Il devrait vraiment s'appeler CopyToNewArrayWithSize. Sous le capot, cette API va créer un nouveau tableau et copier les données spécifiées dans ce tableau. Le nouveau tableau est ensuite renvoyé par référence.

En ce qui concerne la collecte des ordures. En réinitialisant la propriété Lignes au nouveau tableau, vous avez réussi à supprimer la référence d'origine du tableau. Tant qu'il n'y a pas d'autres références au tableau, il sera collecté à un moment donné dans le futur.

+0

Un "oui" aurait suffi, mais merci d'avoir pris le temps d'expliquer différemment! :) Tant que les cordes que je "popping" hors de la fin obtiennent GC'ed (à condition qu'ils ne sont pas référencés ailleurs bien sûr), je suis heureux. –

0

Oui, le tableau d'origine et les chaînes qui ne sont plus utilisés sont collectés correctement.

Si vous calculez la taille que vous souhaitez avant de créer la matrice, vous n'avez pas besoin d'appeler Resize (car cela créera une autre copie du tableau).

// Adds text to the beginning of the log RTB 
// Also keeps the log RTB trimmed to 100 lines 
int size = Math.Min(rtbLog.Lines.Length + 1, 100); 
string[] lines = new string[size]; 
lines[0] = "text"; 
Array.Copy(rtbLog.Lines, 0, lines, 1, size - 1); 
rtbLog.Lines = lines; 
+0

Bon point, merci. –