Question

Donc, si j'itère en utilisant une boucle foreach et que j'ai une fonction à l'intérieur qui prend un argument de l'objet itéré de la liste, et disons que je lui attribue une valeur différente. Pourquoi ne dois-je pas utiliser ou ref? Je pensais que cela n'était passé que par valeur si vous n'utilisiez pas out ou ref .... Je sais qu'un ref doit avoir initialisé la variable avant et out, il vous suffit de définir sa valeur avant de renvoyer la méthode.

Il semble que si vous parcourez une liste par une liste et transmettez un objet dans son objet passé par référence. Prenons l'exemple suivant.

Exemple

class Program
    {
        static void Main(string[] args)
        {

            List<Foo> list = new List<Foo>();
            list.Add(new Foo() { Bar = "1" });
            list.Add(new Foo() { Bar = "2" });



            foreach (var f in list)
            {
                Foo f2 = f; 
                Console.WriteLine("SetFoo Pre: " + f2.Bar);
                SetFoo(f2);
                Console.WriteLine("SetFoo Post: " + f2.Bar);

                Console.WriteLine("SetFooRef Pre: " + f2.Bar);
                SetFooRef(ref f2);
                Console.WriteLine("SetFooRef Post: " + f2.Bar);
                Console.WriteLine("");
            }




            Console.WriteLine("");

            int i = 0;
            // Not using ref keyword
            Console.WriteLine("SetI Pre: " + i);
            SetI(i);
            Console.WriteLine("SetI Post: " + i);

            // Using ref keyword
            Console.WriteLine("SetRefI Pre: " + i);
            SetRefI(ref i);
            Console.WriteLine("SetRefI Post: " + i);
        }


        private static void SetRefI(ref int i)
        {
            i = 3;
            Console.WriteLine("SetRefI Inside: " + i);
        }

        private static void SetI(int i)
        {
            i = 2;
            Console.WriteLine("SetI Inside: " + i);
        }

        private static void SetFooRef(ref Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithRef");
            Console.WriteLine("SetFooRef Inside: " + f.Bar);
        }

        private static void SetFoo(Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithoutRef");
            Console.WriteLine("SetFoo Inside: " + f.Bar);
        }
    }


    class Foo
    {
        public string Bar { get; set; }
    }

Sortie:

  

SetFoo Pre: 1 SetFoo À l'intérieur: 1 ::
  WithoutRef SetFoo Post: 1 SansRef
  SetFoo Pre: 1 :: WithoutRef SetFoo
  Inside: 1 :: WithoutRef :: WithRef
  SetFoo Post: 1 WithoutRef :: WithRef

     

SetFoo Pre: 2 SetFoo À l'intérieur: 2 ::
  WithoutRef SetFoo Post: 2 SansRef
  SetFoo Pre: 2 :: WithoutRef SetFoo
  Inside: 2 :: WithoutRef :: WithRef
  SetFoo Post: 2 WithoutRef :: WithRef

     

SetI Pre: 0 SetI Inside: 2 SetIPost: 0

     

SetRefI Pre: 0 SetRefI Inside: 3
  SetRefI Post: 3

Je comprends les références avec l'exemple entier mais pas l'exemple d'itération d'objet Foo ci-dessus.

Merci!

Était-ce utile?

La solution

La référence est transmise par valeur. Donc, la méthode peut toujours changer le contenu de l'objet, mais elle ne peut pas changer à quel objet votre variable fait référence.

Voir mon article sur la transmission de paramètres pour plus d'informations, ainsi que mon article sur types de référence et types de valeur .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top