none
Stockage d'une référence en C# RRS feed

  • Question

  • Je suis en train de développer quelques objets de type "métiers" pour une petite application ouvrant plusieurs bases de données. Ces mêmes objets travailleront un coup sur une base, un coup sur l'autre. J'ai également un objet qui gère mes accès aux bases de données (via un DbConnection).

     

    Pour éviter d'avoir à passer une référence à mon objet gérant les accès à la base de données à toutes les méthodes des autres objets, je voulais passer la référence sur mon objet base de données lors de la construction des autres objets, le stocker en private afin de pouvoir l'utiliser quand nécessaire.

     

    Mais je ne sais pas comment stocker une référence vers un objet A dans un objet B ? Je ne veut pas utiliser une copie de l'objet A (passage par valeur) mais bien travailler avec une référence sur l'objet A. La syntaxe "private ref MonClasse m_monObjet;" ne fonctionne pas.

     

    Merci d'avance.

     

    PS : savez-vous où je peux trouver des explications claires et rpécises sur la gestion de la mémoire en C# ? J'aimerais bien connaitre le mécanisme afin d'éviter de trop dupliquer des objets en mémoire.

     

    lundi 9 juillet 2007 12:15

Réponses

  • "ref" sert uniquement à indiquer que vous passer la référence d'une référence d'une classe...

     

    Je m'explique :

     

    Imaginons la classe ci-dessous :

     

    Code Snippet

    public class C

    {

        private int a;

     

        public C(int a)

        {

             this.a = a;

        }

    }

      

    ..2 méthodes suivantes pour les essais :

     

    Code Snippet

    public void SansRef(C reference)

    {

           reference = new C(1664);

    }

    public void AvecRef(ref C reference)

    {

          reference = new C(1664);

    }

      

    ..et un petit main :

     

    Code Snippet

    static void Main()

    {

           C c1;

           C c2;

     

           c1 = new C(8000);

           c2 = new C(8000);

     

          SansRef(c1);

          Console.Write(c1.a);

     

          AvecRef(c2);

          AvecRef(c2.a);

    }

     

     

    Lors de l'execution de ce main vous verrez apparaitre : 8000 et 1664

    Dans la méthode SansRef, vous passez en paramètre une référence à c1 et plus exactement une copie de la référence à c1. Hors si vous modifiez dans cette méthode la référence que désigne cette copie, cela n'impactera pas la l'objet référencé par c1.

    Contrairement à AvecRef, vous désignez la référence de la référence à c2, pour faire plus simple le paramètre "reference" de la méthode AvecRef est la référence même de c2.

     

    Si malgré ces explications vous n'avez toujours pas compris voilà "la traduction" avec les pointeurs en langage C++ (ce qui est beaucoup plus parlant) :

     

    Code Snippet

    void SansRef(C* reference);

    void AvecRef(C** reference);

     

    //Les appels se font ainsi :

    static void Main()

    {

           C* c1;

           C* c2;

     

           c1 = new C(8000);

           c2 = new C(8000);

     

          SansRef(c1);

          Console.Write(c1.a);

     

          AvecRef(&c2);

          Console.Write(c2.a);

    }

     

    Cordialement

    mercredi 11 juillet 2007 12:50
    Modérateur

Toutes les réponses

  • En .NET comme sous Java tout objet qui est de type "class" est automatiquement manipulé par référence. Ces objets sont alloué dans le tas (c'est à dire directement en mémoire). Les objet de type "struct" (int, float,...etc) sont manipulés par valeur et sont alloué sur la pile.

     

    Dans votre cas vous pouvez directement faire :

    private MonClasse m_monObjet;

     

    Pour stocker une référence à votre objet MonClasse.

     

    Cordialement

    lundi 9 juillet 2007 19:28
    Modérateur
  • Merci pour l'information.

     

    Donc, si je comprends bien, le mot clé "ref" ne sert à rien pour les objets de type "class" et les interfaces MaMethode(MaClass objet) ou MaMethode(ref MaClass objet) sont équivalentes. Le mot clé ref  n'est utilie que pour les types "struct". C'est bien cela ?

    mercredi 11 juillet 2007 09:08
  • "ref" sert uniquement à indiquer que vous passer la référence d'une référence d'une classe...

     

    Je m'explique :

     

    Imaginons la classe ci-dessous :

     

    Code Snippet

    public class C

    {

        private int a;

     

        public C(int a)

        {

             this.a = a;

        }

    }

      

    ..2 méthodes suivantes pour les essais :

     

    Code Snippet

    public void SansRef(C reference)

    {

           reference = new C(1664);

    }

    public void AvecRef(ref C reference)

    {

          reference = new C(1664);

    }

      

    ..et un petit main :

     

    Code Snippet

    static void Main()

    {

           C c1;

           C c2;

     

           c1 = new C(8000);

           c2 = new C(8000);

     

          SansRef(c1);

          Console.Write(c1.a);

     

          AvecRef(c2);

          AvecRef(c2.a);

    }

     

     

    Lors de l'execution de ce main vous verrez apparaitre : 8000 et 1664

    Dans la méthode SansRef, vous passez en paramètre une référence à c1 et plus exactement une copie de la référence à c1. Hors si vous modifiez dans cette méthode la référence que désigne cette copie, cela n'impactera pas la l'objet référencé par c1.

    Contrairement à AvecRef, vous désignez la référence de la référence à c2, pour faire plus simple le paramètre "reference" de la méthode AvecRef est la référence même de c2.

     

    Si malgré ces explications vous n'avez toujours pas compris voilà "la traduction" avec les pointeurs en langage C++ (ce qui est beaucoup plus parlant) :

     

    Code Snippet

    void SansRef(C* reference);

    void AvecRef(C** reference);

     

    //Les appels se font ainsi :

    static void Main()

    {

           C* c1;

           C* c2;

     

           c1 = new C(8000);

           c2 = new C(8000);

     

          SansRef(c1);

          Console.Write(c1.a);

     

          AvecRef(&c2);

          Console.Write(c2.a);

    }

     

    Cordialement

    mercredi 11 juillet 2007 12:50
    Modérateur