En C #, j'ai toujours pensé que les variables non primitives étaient passées par référence et les valeurs primitives passées par valeur.
Ainsi, lors du passage à une méthode d'un objet non primitif, tout ce qui est fait à l'objet dans la méthode affectera l'objet transmis. (Trucs C # 101)
Cependant, j'ai remarqué que lorsque je passe un objet System.Drawing.Image, que cela ne semble pas être le cas? Si je passe un objet system.drawing.image à une autre méthode et charge une image sur cet objet, puis laisse cette méthode hors de portée et retourne à la méthode appelante, cette image n'est pas chargée sur l'objet d'origine?
Pourquoi est-ce?
Réponses:
Les objets ne sont pas du tout passés. Par défaut, l'argument est évalué et sa valeur est transmise, par valeur, comme valeur initiale du paramètre de la méthode que vous appelez. Maintenant, le point important est que la valeur est une référence pour les types de référence - un moyen d'accéder à un objet (ou null). Les modifications apportées à cet objet seront visibles par l'appelant. Cependant, la modification de la valeur du paramètre pour faire référence à un autre objet ne sera pas visible lorsque vous utilisez la valeur de passage, qui est la valeur par défaut pour tous. types.
Si vous souhaitez utiliser le passage par référence, vous devez utiliser
out
ouref
, que le type de paramètre soit un type de valeur ou un type de référence. Dans ce cas, la variable elle-même est effectivement transmise par référence, de sorte que le paramètre utilise le même emplacement de stockage que l'argument - et les modifications apportées au paramètre lui-même sont vues par l'appelant.Alors:
J'ai un article qui va dans beaucoup plus de détails . Fondamentalement, «passer par référence» ne signifie pas ce que vous pensez que cela signifie.
la source
ref
etout
de c #, est-il correct de dire que c # transmet les paramètres de la même manière que Java, c'est-à-dire toujours par valeur Y a-t-il une différence avec Java?Un autre exemple de code pour illustrer cela:
Et la sortie:
la source
Beaucoup de bonnes réponses ont été ajoutées. Je veux toujours contribuer, peut-être que cela clarifiera un peu plus.
Lorsque vous passez une instance en tant qu'argument à la méthode, elle transmet la
copy
de l'instance. Maintenant, si l'instance que vous passez est unvalue type
(réside dans lestack
) vous passez le copie de cette valeur, donc si vous la modifiez, elle ne sera pas reflétée dans l'appelant. Si l'instance est un type de référence, vous transmettez la copie de la référence (réside à nouveau dans lestack
) à l'objet. Vous avez donc obtenu deux références au même objet. Les deux peuvent modifier l'objet. Mais si dans le corps de la méthode, vous instanciez un nouvel objet, votre copie de la référence ne fera plus référence à l'objet d'origine, elle se référera au nouvel objet que vous venez de créer. Vous finirez donc par avoir 2 références et 2 objets.la source
Je suppose que c'est plus clair quand vous le faites comme ça. Je recommande de télécharger LinqPad pour tester des choses comme ça.
Et cela devrait produire
WontUpdate
Prénom: Egli, Nom: Becerra
Mettre à jour implicitement
Prénom: Favio, Nom: Becerra
Mise à jourExplicitement
Prénom: Favio, Nom: Becerra
la source
Lorsque vous passez l'
System.Drawing.Image
objet type à une méthode, vous passez en fait une copie de référence à cet objet.Donc, si à l'intérieur de cette méthode, vous chargez une nouvelle image, vous chargez en utilisant une référence nouvelle / copiée. Vous ne modifiez pas l'original.
la source
Comment avez-vous passé l'objet à la méthode?
Faites-vous du nouveau à l'intérieur de cette méthode pour objet? Si oui, vous devez utiliser la
ref
méthode.Le lien suivant vous donne une meilleure idée.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
la source
Dans Pass By Reference Vous ajoutez seulement "ref" dans les paramètres de la fonction et encore une chose que vous devriez déclarer la fonction "statique" car le principal est statique (#
public void main(String[] args)
)!la source