2010-08-18 4 views
1

J'utilise la classe générique TDictionary de Delphi 9. Mon TDictionary ressemble à ceci:TDictionary de Delphi, mes objets de valeur insèrent comme nulle

g_FileHandlers : TDictionary<String, TList<String>>; 

Et, donc j'initialiser le TDictionary comme ceci:

g_FileHandlers := TDictionary<String, TList<String>>.Create; 

J'ai un TList, que je suis aussi l'initialisation, afin que je puisse l'utiliser pour remplir le TDictionary. Je suis en boucle sur certaines données de fichier que j'utilise pour peupler le TList/TDictionary, et j'essaie de réutiliser le même TList à insérer dans le TDictionary que la valeur. Lors de la première insertion dans le TDictionary, la valeur TList de l'élément existe et contient les données. Sur la deuxième, et les itérations suivantes, bien que les valeurs TList soient toutes nulles.

g_FilePaths := TList<String>.Create; 

Il me semble que tout cela est fait par référence. Est-ce que quelqu'un sait comment ajouter un TList à mon TDictionary par valeur, au lieu de référence?

Merci

// Create our dictionary of files and handlers 
    for i := 0 to g_FileList.Count - 1 do 
    begin 
    g_HandlerName := AnsiMidStr(g_FileList[i], 2, Length(g_FileList[i])); 
    g_HandlerName := AnsiMidStr(g_HandlerName, 1, Pos('"', g_HandlerName) - 1); 

    if i = 0 then 
     g_PreviousHandlerName := g_HandlerName; 

    if AnsiCompareText(g_HandlerName, g_PreviousHandlerName) = 0 then 
    begin 
     g_FilePath := AnsiMidStr(g_FileList[i], Length(g_HandlerName) + 5, Length(g_FileList[i])); 
     g_FilePath := AnsiMidStr(g_FilePath, 1, Length(g_FilePath) - 1); 
     g_FilePaths.Add(g_FilePath); 
    end 
    else 
    begin 
     g_FileHandlers.Add(g_PreviousHandlerName, g_FilePaths); 

     g_FilePaths.Clear; 
     g_FilePath := AnsiMidStr(g_FileList[i], Length(g_HandlerName) + 5, Length(g_FileList[i])); 
     g_FilePath := AnsiMidStr(g_FilePath, 1, Length(g_FilePath) - 1); 
     g_FilePaths.Add(g_FilePath); 
    end; 

    if AnsiCompareText(g_HandlerName, g_PreviousHandlerName) <> 0 then 
     g_PreviousHandlerName := g_HandlerName; 

    if i = g_FileList.Count - 1 then 
     g_FileHandlers.Add(g_HandlerName, g_FilePaths); 
    end; 
    g_FilePaths.Free; 

Répondre

2

La "valeur" TList vous avez est une référence, de sorte que vous sont ajoutant par valeur. (Ajouter par référence signifierait que si vous changiez la valeur de g_FilePaths, les valeurs stockées dans le dictionnaire changeraient également, mais cela ne se produit pas - ces valeurs continuent de se rapporter au même objet TList avec lequel elles ont commencé

TDictionary ne fait pas de copie en profondeur des objets, comme rien d'autre: vous allez juste devoir mordre la balle et créer un nouvel objet TList pour chaque élément que vous souhaitez ajouter.Vous pouvez réutiliser la variable globale g_FilePaths si vous voulez, mais vous devez instancier un nouvel objet à chaque itération

+0

Je suis d'accord et voudrais aussi suggérer que l'OP utilise TObjectDictionary et crée en utilisant "TObjectDictionary > .Create ([doOwnsValues]); "pour éviter les fuites de mémoire des listes quand les éléments sont supprimés. –

Questions connexes