2010-06-16 25 views
1

Désolé, je suis à la fois épais et paresseux, mais surtout paresseux. En fait, même pas ça. J'essaie de gagner du temps pour pouvoir faire plus en moins de temps car il y a beaucoup à faire.Copie-t-il la référence ou l'objet?

Copie-t-il la référence ou les données réelles de l'objet? Je pense que je connais la réponse à coup sûr: il ne fait que copier la référence. Mais je ne suis même pas sûr de savoir pourquoi je demande cela.

Je suppose que ma seule préoccupation est, si, après l'instanciation Foo en appelant sa cteur paramétrés si je avais besoin avec toPass, pour vous assurer que le CNV je passé comme toPass et le domaine privé NVC _nvc avait exactement le même contenu, je aurait juste besoin de comparer leurs références, non?

+0

Gardez à l'esprit que si vous dites 'nouveau Foo (toPass)', puis plus tard, le point 'toPass' à un autre objet (que ce soit une nouvelle ou instance existante), puis' '_nvc' dans les foo' sera pas plus se réfèrent au même objet que 'toPass'. L'égalité de référence ne sera plus utile (sauf si c'est votre * seule * considération). –

+0

Merci, Anthony. Je comprends que. Oui, j'ai juste besoin de faire une vérification immédiate des références juste après un nouveau Foo (toPass), puis de supprimer toPass. –

Répondre

3

Oui, c'est correct. Cependant, si vous voulez comparer toPass et Foo._nvc plus tard, vous voudrez peut-être faire une comparaison par membre si différente mais les collections équivalentes comparent égales.

+0

Merci, Matthew. Le 'toPass' et l'opération de création de' Foo' avec ça sera un one-off et ma comparaison d'équivalence doit aussi être un one-off, donc je n'aurai pas à faire face à la situation que vous décrivez, mais vous faites un point très intéressant. –

1

En un mot, oui.

+0

Un grand merci, Steven. –

-2

Editer: Oui, ceci a copié la valeur de la référence.

Je suis d'accord aussi avec Matthew Flaschen sur la copie en profondeur comparer - et aussi surcharger votre opérateur égalité comparer

+0

raison de la downvote? – VoodooChild

+0

Ce n'est pas * 'ByRef'. Le C# équivalent à cela est le mot-clé 'ref'. Si * était * 'ref', le constructeur pourrait affecter la valeur de' toPass' dans 'Main'. –

+0

quand il fait "new Foo (toPass)", n'envoie-t-il pas la référence de l'objet pour qu'elle soit copiée dans "_nvc"? Et n'est-ce pas pourquoi quand il compare ces deux variables se traduira par l'égalité? Qu'est-ce que j'ai raté? – VoodooChild

0

Vous passez un type de référence en termes de valeur. Vous pouvez modifier les données pointées par la référence (par exemple ajouter de nouveaux éléments à la collection) et les modifications seront répercutées sur l'appelant. Comme Matthew l'a souligné, vous devrez peut-être encore vérifier les différents objets encore équivalents.

En supposant que vous respectiez l'utilisation que vous avez imprimée et n'effectuez aucune «nouvelle» opération, les références d'objet resteront équivalentes.

public class Foo 
    { 
     public NameValueCollection _nvc = null; 

     public Foo(NameValueCollection nvc) 
     { 
      //this is cool 
      _nvc = nvc; 
      _nvc.Add("updated", "content"); 

      //this isn't cool. Now you have a new object with equivalent members and you should follow Matthew's advice 
      //_nvc = new NameValueCollection(); 
      //_nvc.Add("foo", "bar"); 
      //_nvc.Add("updated", "content"); 
     } 
    } 

    public class Bar 
    { 
     public static void Main() 
     { 
      NameValueCollection toPass = new NameValueCollection(); 
      toPass.Add("foo", "bar"); 
      Foo f = new Foo(toPass); 

      if (Object.Equals(toPass, f._nvc)) 
       Console.WriteLine("true"); 
      else 
       Console.WriteLine("false"); 
      Console.ReadLine(); 
     } 
    } 
+0

Merci pour le petit tutoriel. Cela renforce ma compréhension du sujet. –