La valeur du dictionnaire C # s’efface lorsque j’efface la liste qui lui était précédemment atsortingbuée… pourquoi?

Dictionary <string, List > saleItemNew = new Dictionary<string, List> (); saleItems = new List  (); saleItemNew.Add("1", saleItems); 

À ce stade, la liste du dictionnaire a des valeurs.

 saleItems.Clear(); 

Cependant, lorsque j’efface la liste qui lui avait été précédemment atsortingbuée, la liste de valeurs du dictionnaire est maintenant vide … pourquoi?

Le dictionnaire contient la même référence à la liste. La modification de la liste modifiera donc les deux références.

Documentation Microsoft sur les types de référence: http://msdn.microsoft.com/en-us/library/490f96s2.aspx

La raison en est que le dictionnaire est une référence et non un type de valeur. Lorsque vous affectez un dictionnaire à une autre variable, la copie en profondeur n’est pas effectuée. Au lieu de cela, il pointe simplement une autre référence sur le même object. Puisqu’il n’y a qu’un seul object, l’effacement via l’une ou l’autre référence sera visible pour les deux références.

Ceci contraste avec les types de valeur dans le .Net Framework. L’affectation d’un type de valeur effectue essentiellement une copie superficielle des données et crée deux objects indépendants. Notez que si le type de valeur a un champ de référence, les deux champs des deux types de valeur pointeront toujours sur le même object.

cela a à voir avec l’utilisation de la mémoire et les pointeurs. Vous avez une stack et un tas lors de l’allocation de mémoire pour des objects, cette mémoire est l’un des tas. Votre variable saleItems est définie sur la stack et pointe vers l’adresse de la mémoire sur le tas. Votre dictionnaire est également sur la stack pointant vers le tas.

quand tu dis:

 saleItems = new List() 

la variable saleItems est poussée sur la stack et contient une adresse mémoire qui pointe vers l’emplacement des données sur le tas. Disons 0x0100 . Maintenant, vous ajoutez un nouvel DictionaryItem à votre dictionnaire. DictionaryItem est placé sur le tas avec deux propriétés, Key et Value. Dans ce cas, vous avez ajouté saleItems tant que Value . Par conséquent, Value a également l’adresse 0x0100 . DictionaryItem.Value pointe maintenant vers la même mémoire que saleItems. Lorsque vous appelez saleItems.Clear, vous dites que vous devez rechercher la liste à l’adresse 0x0100 et supprimer tous les éléments. Ainsi, le dictionnaire et la variable deviennent tous deux vides car ils pointent vers la même mémoire. Ce que vous voulez faire, c’est dire saleItems = new List(); encore. Désormais, saleItems pointera vers une nouvelle adresse sur le tas (par exemple 0x0200 ). DictionaryItem.Value pointe toujours sur l’adresse mémoire 0x0100 afin que vous puissiez agir sur la variable saleItems sans affecter les données de votre dictionnaire.

Pour plus d’informations sur les stacks et les tas en c #, essayez cet article: http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-14b143446

L’ajout de la liste au dictionnaire est juste une copie superficielle … Une nouvelle liste avec les mêmes valeurs n’est pas créée et ajoutée (une copie complète); une référence à l’ancienne liste est plutôt ajoutée.

Il utilise la même référence.

Une meilleure façon de le faire est

 Dictionary > saleItemNew = new Dictionary>(); saleItemNew.Add("1", new List()); 

Et pour le nettoyage

 saleItemNew["1"] = new List(); 

Comme il s’agit d’un type de référence, seul le pointeur sur les valeurs en mémoire est copié, pas les valeurs elles-mêmes. Vous pouvez spécifier le comportement que vous souhaitez avec un constructeur:

De point net perls: // // Copiez le dictionnaire dans un deuxième object. // Dictionnaire copy = new Dictionary (dictionary);