10
votes

Passant par Réf?

Je suis toujours confondu de passer par réf.

Si j'ai un objet de cache que je veux être accessible / disponible sur un certain nombre d'objets, et je l'injecte à l'aide de l'injection de constructeur. Je veux que cela affecte l'objet de cache unique que j'ai créé. EG. P>

public class Cache {

   public void Remove(string fileToRemove) {
      ...
   }
}

public class ObjectLoader {

   private Cache _Cache;

   public ObjectLoader(Cache cache) {

   }

   public RemoveFromCacheFIleThatHasBeenDeletedOrSimilarOperation(string filename) {
      _Cache.Remove(fileName);
   }
}


0 commentaires

4 Réponses :


7
votes

Utilisez le mot-clé "Réf 'lorsque vous devez modifier quelle est la référence pointant vers . Lorsque vous passez un type de référence dans une méthode est transmis par la valeur, mais la valeur est une copie de cette référence qui est transmise à la méthode. Cela signifie que vous pouvez modifier l'état général (c.-à-d. Propriétés / champs) de l'objet renvoyé, mais si vous essayez de modifier ce que les points de référence vous affecteront uniquement la copie.

Par exemple, étant donné cette méthode. .. xxx

Nous pouvons passer dans l'argument, puis voir s'il était affecté: xxx

maintenant, si nous avait défini la méthode à l'aide du mot-clé 'ref' ... xxx

la sortie serait "true", car la référence réelle a été transmise à la méthode, pas une copie. Nous avons modifié ce que cette référence pointe sur la fonction et que nous voyons les effets de ces changements.

Vous créez simplement un nouveau pointeur sur l'objet sur le tas lorsque vous omettez le mot-clé "REF". Si vous changez un pointeur, vous ne changerez pas l'autre.

...

Donc, pour répondre à votre question; Non, vous n'avez pas besoin d'utiliser le mot-clé "REF" pour modifier l'état de votre objet de cache unique lorsqu'il est transmis à une méthode.


2 commentaires

Je suis en désaccord :) Mais pour les personnes C / C ++, c'est la différence entre * (ou & &) et ** :)


Nitpick: 2e exemple - Vous accédez à une propriété statique.



-3
votes

Les objets sont automatiquement passés par référence même lorsque vous les déclarez transmis par la valeur dans les arguments de la fonction, dans le cadre .NET.

Ceci est dû au fait que l'objet lui-même est un type de référence, vous pouvez donc modifier les membres de l'objet, même si vous ne pouvez pas remplacer l'objet lui-même.

voir

http://msdn.microsoft.com/ EN-US / Bibliothèque / AA903253 (vs.71) .aspx


2 commentaires

Les objets sont passés par la valeur, comme tout le reste. La différence avec les objets (lit: types de référence) est que la référence est transmise par la valeur.


Tous les paramètres sont transmis par la valeur en C # à moins que vous n'utilisez explicitement Ref ou Out. Cependant, dans le cas des types de référence, la référence copiée pointe toujours sur la même instance afin que vous puissiez modifier l'instance, mais pas la référence elle-même.



11
votes

Non, vous n'avez pas besoin d'utiliser le mot clé ref dans cette situation.

cache est une classe, c'est un type de référence. Lorsqu'une référence est transmise à une méthode, une copie de la référence (pas l'objet lui-même) est placée dans votre paramètre. Les deux références, à l'intérieur et à l'extérieur, de la méthode indiquent le même objet sur le tas, et la modification des champs de l'objet à l'aide d'une utilisation sera reflétée dans l'autre.

Ajout de Ref à votre méthode Call passe dans la référence d'origine. Ceci est utile dans une situation où vous seriez réaffectant (c'est-à-dire en appelant nouveau ) l'emplacement des points de référence à partir d'une méthode d'appel.


0 commentaires

1
votes

Je pense que vous vous demandez combien de copies de l'objet cache seront créées. Vous voulez seulement qu'une copie soit partagée par plusieurs objets clients. Eh bien, il y a une règle très simple que vous vous souviendrez en C #, chaque fois que vous voulez savoir combien de copies séparées de votre objet seront créées.

Si le type de l'objet est déclaré avec le mot clé class , puis il y a un seul moyen de faire une nouvelle instance de Il: avec le mot-clé neuf .

Il existe des exceptions mineures à cette option: vous pouvez appeler des méthodes de BCL qui créent des objets, mais le point est qu'il est explicite. Vous devez demander spécifiquement que cela se produise. La langue ne créera pas automatiquement des copies des objets .

Donc, dans votre exemple, vous avez une classe class appelé cache , et vous savez donc certainement que vous pouvez transmettre des variables de type cache autant que vous le souhaitez, et aucune autre copie de cache sera créée. Toutes les variables qui ont cet objet qui leur sont attribuées seront "pointant" sur le même objet d'origine. En effet, une variable cache ne stocke pas l'objet lui-même, mais uniquement l'emplacement d'un objet cache en mémoire.

contraste avec quoi arrive si vous déclarez un type struct au lieu d'une classe . Maintenant, lorsque vous déclarez une variable de ce type, la variable elle-même doit être suffisamment grande pour stocker toutes les données déclarées dans le struct . Chaque variable est une copie séparée. Chaque paramètre est une copie séparée.

Vous pouvez remplacer cela en ajoutant le mot clé ref , mais c'est un mot clé assez inhabituel dans la plupart des programmes. Le mot clé out est plus courant et est la meilleure pensée comme un moyen de donner une méthode plus d'une valeur de retour.

Quel effet ref avoir sur une variable si elle est de type ? Dans votre exemple: xxx

Je pourrais construire deux chargeurs d'objets comme ceci: xxx

Combien d'objets avons-nous seulement créé ? Comptez simplement les mots-clés nouveaux . Maintenant, supposons que nous ajoutions le mot-clé ref xxx

caché à l'intérieur de ce constructeur, j'ai créé un autre cache et stocké-le dans le paramètre i a été réussi. Parce que c'est un paramètre ref , j'ai affecté la variable de l'appelant! Donc, dans le code d'appel: xxx

Nous avons maintenant cinq utilisations de Nouveau : trois dans l'extrait ci-dessus, plus deux appels vers le Chargeur d'opposition Constructeur. Chaque fois que le constructeur d'objets est appelé, nous le transmettons c . Nous devons mettre le mot-clé ref , qui est une très bonne chose car elle permet à la personne de lire le code savoir que quelque chose d'étrange se passe. La variable C pointe vers un autre cache après lecteur d'opposition Le constructeur de 'S revit. SO B 's frother finit par stocker un pointeur sur un autre cache sur à A << P> Inutile de dire que ce serait un modèle assez désordonné pour que le code ait. Ce serait encore pire si nous n'avions pas besoin de mettre le mot-clé ref sur le site d'appel!


0 commentaires