109 votes

Quelle est la différence entre un type de référence et le type de valeur en c#?

Un mec m'a posé cette question il y a quelques mois et je n'arrivais pas à l'expliquer en détail. Quelle est la différence entre un type de référence et une valeur de type en C#?

Je sais que les types de valeur sont int, bool, float,, etc et les types de référence sont delegate, interface, etc. Ou est-ce mal?

Pouvez-vous me l'expliquer d'une manière professionnelle?

193voto

Jon Skeet Points 692016

Vos exemples sont un peu bizarre parce que tout int, bool et float sont des types spécifiques, les délégués et les interfaces sont des sortes de type - tout comme struct et enum sont des sortes de types de valeur.

J'ai écrit une explication des types de référence et des types de valeur dans cet article. Je serais heureux de se développer sur tous les bits que vous trouverez à confusion.

Le "TL;DR" version est de penser à ce que la valeur d'une variable ou expression d'un type particulier. Pour un type de valeur, la valeur est l'information elle-même. Pour un type de référence, la valeur est une référence qui peut être nul ou peut-être un moyen d'accéder à un objet contenant les informations.

Par exemple, pensez à une variable comme un morceau de papier. Il pourrait avoir de la valeur "5" ou "faux" écrit sur elle, mais il ne pouvait pas avoir ma maison... il devait avoir des instructions à ma maison. Ces directions sont l'équivalent d'une référence. En particulier, deux personnes pourraient avoir différents morceaux de papier contenant les mêmes instructions à ma maison, et si une personne a suivi ces instructions et peint ma maison rouge, puis la seconde personne de voir que le changement aussi. Si ils avaient séparé les photos de ma maison sur le papier, puis une personne de la coloration des papier ne change pas l'autre personne se livre à tous.

31voto

HDA Points 2590

Type de la valeur:

Détient une certaine valeur, pas des adresses de mémoire

Exemple:

Struct

Stockage:

Types de valeur sont stockées sur la pile.

Avantages:

Un type de la valeur n'a pas besoin supplémentaire de collecte des ordures. Il obtient des ordures collectées en collaboration avec l'instance dans laquelle il vit. Les variables locales dans les méthodes de nettoyer méthode de congé.

Inconvénients:

  1. Lorsqu'un grand ensemble de valeurs qui sont passés à une méthode de la réception de la variable en fait des copies, donc il y a deux redondant valeurs dans la mémoire.

  2. Comme les classes sont raté.la perte de tous les avantages de la programmation orientée objet

Type de référence:

Titulaire d'une adresse en mémoire d'une valeur non valeur

Exemple:

Classe

Stockage:

Stockées sur le tas

Avantages:

  1. Lorsque u passer une variable de référence à une méthode et elle la change en effet des changements de la valeur d'origine tandis que dans les types de valeur d'une copie de la variable donnée est prise et que la valeur est modifiée.

  2. Lorsque la taille de la variable est plus grand type de référence est bon

  3. Que la classe vient dans ce type de variable oops est promu pour qu'il donne la réutilisabilité de ces avantages de la programmation orientée objet

Inconvénients:

Plus de travail de référencement lors de l'attribution et déréférence lors de la lecture de la valeur.extra surcharge pour le garbage collector

13voto

Jimmy Chandra Points 3562

Je l'ai trouvé plus facile de comprendre la différence entre les deux si vous savez comment l'ordinateur allouer des aliments en mémoire et de savoir ce qu'est un pointeur.

De référence est généralement associé à un pointeur. Sens de l'adresse mémoire où votre variable résident est effectivement une autre adresse mémoire de l'objet réel dans un emplacement différent de la mémoire.

L'exemple que je vais donner est grossièrement simplifiée, afin de prendre cela avec un grain de sel.

Imaginez la mémoire de l'ordinateur est un tas de boîtes postales dans une rangée (de départ w/ Boîte POSTALE 0001 à une Boîte POSTALE n) qui peut contenir quelque chose à l'intérieur. Si les cases postales ne pas le faire pour vous, essayez une table de hachage ou d'un dictionnaire ou d'un tableau ou quelque chose de similaire.

Ainsi, lorsque vous faites quelque chose comme:

var a = "Bonjour";

l'ordinateur va effectuer les opérations suivantes:

  1. allouer de la mémoire (disons à partir à l'emplacement de mémoire 1 000 pour 5 octets) et de mettre H (1000), e (1001), de l (1002), l (1003) et o (1004).
  2. allouer quelque part dans la mémoire (par exemple au lieu 0500) et affecté comme une variable.
    Donc c'est un peu comme un alias (0500 est une).
  3. attribuer de la valeur à cet emplacement de la mémoire (0500) à 1000 (qui est l'endroit où la chaîne Hello début en mémoire). Ainsi, la variable a est maintenant une référence pour le départ de l'emplacement de mémoire de la chaîne "Hello".

Type de valeur doit tenir la chose réelle dans son emplacement de mémoire.

Ainsi, lorsque vous faites quelque chose comme:

var a = 1;

l'ordinateur va effectuer les opérations suivantes:

  1. allouer un emplacement de mémoire dire à 0500 et l'assigner à une variable (le même alias chose)
  2. mettre la valeur 1 (à l'emplacement de la mémoire 0500).
    Notez que nous ne sommes pas d'allouer de la mémoire supplémentaire pour contenir la valeur réelle (1). Donc un est en fait la tenue de la valeur réelle et c'est pourquoi il est appelé le type de valeur.

9voto

XIVSolutions Points 2534

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:

  1. Créé 2 emplacements de mémoire suffisante pour stocker un entier de 32 bits des valeurs.
  2. Placé à une valeur de 3 dans l'allocation de mémoire affectée à Un
  3. 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 . . .

1voto

Lucas S. Points 175

"Variables qui sont basés sur la valeur directement les types de contenir des valeurs. Affectation d'une variable de type valeur à une autre copie le contenue de la valeur. Ce qui diffère de l'affectation de référence des variables de type, qui copie une référence à l'objet, mais pas l'objet lui-même." à partir de Microsoft bibliothèque.

Vous pouvez trouver une réponse plus complète ici et ici.

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:

X