78 votes

Type de référence en C#

Considérer ce code:

public class Program
{
    private static void Main(string[] args)
    {
        var person1 = new Person { Name = "Test" };
        Console.WriteLine(person1.Name);

        Person person2 = person1;
        person2.Name = "Shahrooz";
        Console.WriteLine(person1.Name); //Output: Shahrooz
        person2 = null;
        Console.WriteLine(person1.Name); //Output: Shahrooz
    }
}

public class Person
{
    public string Name { get; set; }
}

Évidemment, lors de l'affectation d' person1 de person2 et de la Name de la propriété de l' person2 est modifié, l' Name de person1 seront également modifiés. person1 et person2 ont la même référence.

Pourquoi est-il que lorsqu' person2 = null, person1 variable ne sera pas nulle non plus?

184voto

Andrei Points 25595

Les deux person et person2 sont des références, pour le même objet. Mais ce sont des références différentes. Ainsi, lorsque vous sont en cours d'exécution

person2 = null;

vous êtes en changeant uniquement de référence person2, laissant de référence person et l'objet correspondant inchangé.

Je suppose que la meilleure façon d'expliquer ce que c'est avec une illustration simplifiée. Voici comment la situation avant d' person2 = null:

Before null assignment

Et voici la photo après le nul de la cession:

Enter image description here

Comme vous pouvez le voir sur la deuxième photo, person2 références rien (ou null, à proprement parler, car rien de référence et la référence à l' null sont des conditions différentes, voir le commentaire de Rune FS), tandis que l' person fait toujours référence à un objet existant.

56voto

Habib Points 93087

Envisager person1 et person2 que les pointeurs à un emplacement de stockage. Dans la première étape, seulement person1 est en tenant l'adresse de l'objet de stockage et, plus tard, person2 est en tenant l'adresse de l'emplacement de la mémoire de l'objet de stockage. Plus tard, lorsque vous affectez null de person2, person1 reste intact. C'est pourquoi vous voyez le résultat.

Vous pouvez lire: Valeur vs de Référence Types de Joseph Albahari

Avec les types de référence, cependant, un objet est créé dans la mémoire, et ensuite gérée par le biais d'une référence distincte, un peu comme un pointeur.

Je vais essayer de décrire le même concept à l'aide du diagramme suivant.

enter image description here

Créé un nouvel objet de type personne et l' person1 de référence (pointeur) vers l'emplacement de mémoire de stockage.

enter image description here

Créé une nouvelle référence(pointeur) person2 qui pointe vers le même dans le stockage.

enter image description here

Modification de l'objet Nom de la propriété à la nouvelle valeur, par le biais person2 depuis deux références pointent vers le même objet,Console.WriteLine(person1.Name); sorties Shahrooz.

enter image description here

Après l'affectation d' null de person2 de référence, il pointe à rien, mais person1 tient encore la référence à l'objet.

(Enfin pour la gestion de la mémoire, vous devriez voir La Pile Est Un Détail d'Implémentation, la première Partie et La Pile Est Un Détail d'Implémentation, la deuxième Partie de Eric Lippert)

15voto

No Idea For Name Points 10466

Vous avez changé d' person2 de référence null, mais person1 n'est pas le référencement.

Ce que je veux dire c'est que si l'on regarde person2 et person1 avant la cession, puis les deux font référence au même objet. Vous pouvez ensuite affecter person2 = null, de sorte que la personne 2 est maintenant le référencement d'un type différent. Il n'a pas la suppression de l'objet qu' person2 a été référencée.

J'ai créé ce gif pour illustrer cela:

enter image description here

14voto

Simon Whitehead Points 27669

Parce que vous avez mis la référence à l' null.

Lorsque vous définissez une référence à l' null, la référence elle-même est - null.. pas l'objet de références.

Pensez à eux comme une variable qui contient un décalage de 0. person a la valeur de 120. person2 a la valeur de 120. Les données à l'offset 120 est l' Person objet. Lorsque vous faites cela:

person2 = null;

..vous êtes effectivement dire, person2 = 0;. Toutefois, person a encore de la valeur 120.

5voto

Øyvind Bråthen Points 25211

Les deux person et person2 point pour le même objet. Par conséquent, lorsque vous modifiez le nom de l'un d'eux, tous deux se changé (depuis qu'ils pointent sur la même structure dans la mémoire).

Mais lorsque vous définissez person2 de null, vous faites de l' person2 en un pointeur null, ce qui est n'a pas de point pour le même objet que l' person plus. Il l'habitude de faire quelque chose à l'objet lui-même de le détruire, et depuis person des points encore/références de l'objet, il l'habitude de se faire tuer par le garbage collection.

Si vous aussi, vous définissez person = null, et vous n'avez pas d'autres références à l'objet, il sera finalement retiré par le garbage collector.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: