C'est à partir d'un poste de la mine à partir d'un autre forum, il y a deux ans. Alors que la langue est vb.net (contrairement à C#), le Type de Valeur vs Référence type concepts sont uniformes dans l'ensemble .net, et les exemples sont toujours.
Il est également important de se rappeler qu'à l'intérieur .net, TOUS les types techniquement dériver à partir de la base type d'Objet. Les types de valeur sont conçus pour comporter en tant que tels, mais à la fin ils héritent également de la fonctionnalité de la base type d'Objet.
A. les Types de Valeur, ne sont que des qu'ils représentent une zone particulière de la mémoire où une discrète VALEUR est stockée. Types de valeur sont de la taille de mémoire fixe et sont stockés dans la pile, qui est une collection d'adresses de taille fixe.
Lorsque vous effectuez un énoncé comme tel:
Dim A as Integer
DIm B as Integer
A = 3
B = A
Vous avez effectué les opérations suivantes:
- Créé 2 emplacements de mémoire suffisante pour stocker un entier de 32 bits des valeurs.
- Placé à une valeur de 3 dans l'allocation de mémoire affectée à Un
- Placé à une valeur de 3 dans l'allocation de mémoire affectée à B en attribuant la même valeur que la tenue en A.
La Valeur de chaque variable existe discrètement dans chaque emplacement de mémoire.
B. les Types de Référence peuvent être de différentes tailles. Par conséquent, ils ne peuvent pas être stockées dans la "Pile" (rappelez-vous, la pile est une collection d'allocations de mémoire de taille fixe?). Ils sont stockés dans le "Tas Managé". Les pointeurs (ou "références") de chaque élément sur le tas managé sont maintenus dans la pile (Comme une Adresse). Votre code utilise ces pointeurs dans la pile pour accéder à des objets stockés dans le tas managé. Donc si votre code utilise une variable de référence, il est fait à l'aide d'un pointeur (ou "adresse" à un emplacement de mémoire dans le tas managé).
Disons que vous avez créé une Classe nommée clsPerson, avec une chaîne de Propriété de Personne.Nom
Dans ce cas, lorsque vous faites une déclaration comme ceci:
Dim p1 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
Dim p2 As Person
p2 = p1
Dans le cas ci-dessus, la p1.Nom de la Propriété sera de Retour "Jim Morrison", comme vous le souhaitez. Le p2.Nom de la propriété est ÉGALEMENT de retour "Jim Morrison", comme vous le feriez Iintuitively attendre. Je crois que les deux p1 et p2 représentent les adresses distinctes sur la Pile. Cependant, maintenant que vous avez attribué p2 la valeur de p1, les deux p1 et p2 point au MÊME EMPLACEMENT sur le tas managé.
Considérons maintenant CETTE situation:
Dim p1 As clsPerson
Dim p2 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
p2 = p1
p2.Name = "Janis Joplin"
Dans cette situation, Vous avez créé une nouvelle instance de la Classe personne sur le Tas Managé avec un pointeur p1 sur la Pile, qui fait référence à l'objet, et assigné à la Propriété Name de l'objet instance d'une valeur de "Jim Morrison". Ensuite, vous avez créé un autre pointeur p2 dans la Pile, et l'a signalé à la même adresse sur le tas managé comme celui référencé par p1 (quand vous avez fait la déclaration p2 = p1).
Voici le twist. Lorsque vous Attribuez le Nom de la propriété de p2 la valeur "Janis Joplin" vous modifiez la propriété Name de l'objet RÉFÉRENCÉ par les Deux p1 et p2, de telle sorte que, si vous avez exécuté le code suivant:
MsgBox(P1.Name)
'Will return "Janis Joplin"
MsgBox(p2.Name)
'will ALSO return "Janis Joplin"Because both variables (Pointers on the Stack) reference the SAME OBJECT in memory (an Address on the Managed Heap).
Est-ce que cela a du sens?
Dernier. Si vous faites CELA:
DIm p1 As New clsPerson
Dim p2 As New clsPerson
p1.Name = "Jim Morrison"
p2.Name = "Janis Joplin"
Vous avez maintenant deux distincts les Objets de la Personne. Cependant, la minute où vous ne à nouveau:
p2 = p1
Vous avez maintenant de relever à la fois de retour à "Jim Morrison". (Je ne suis pas sûr de savoir exactement ce qui s'est passé à l'Objet sur le Tas référencé par p2 . . . Je PENSE qu'il est aujourd'hui hors de portée. C'est l'un de ces domaines où hopefullly quelqu'un peut me droite . . .). -EDIT: je CROIS que c'est pourquoi vous devez Définir p2 = Rien OU p2 = New clsPerson avant de faire la nouvelle affectation.
Une fois de plus, maintenant, si vous faites CELA:
p2.Name = "Jimi Hendrix"
MsgBox(p1.Name)
MsgBox(p2.Name)
Les deux msgBoxes sera de retour "Jimi Hendrix"
Cela peut être assez déroutant pour un peu, et je vais le dire une dernière fois, j'ai peut-être quelques-uns des détails de mal.
Bonne Chance, et j'espère que d'autres qui savent mieux que moi va venir pour aider à clarifier certains de cela . . .