Domanda

Quindi, se sto iterando usando un ciclo foreach e ho una funzione all'interno che accetta un argomento dell'oggetto iterato dalla lista, e diciamo che ho impostato il suo valore in modo diverso. Perché non devo usare o rif? Ho pensato che fosse passato solo per valore se non lo hai usato o ref .... So che un ref devi aver inizializzato la variabile prima e out devi solo aver impostato il suo valore prima di tornare dal metodo.

Sembra che tu stia iterando attraverso una lista e passi un oggetto nella sua realtà passato per riferimento. Considera il seguente esempio.

Esempio

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; }
    }

Output:

  

SetFoo Pre: 1 SetFoo Interno: 1 ::
  WithoutRef SetFoo Post: 1 senzaRef
  SetFoo Pre: 1 :: WithoutRef SetFoo
  Interno: 1 :: WithoutRef :: WithRef
  SetFoo Post: 1 WithoutRef :: WithRef

     

SetFoo Pre: 2 SetFoo Interno: 2 ::
  WithoutRef SetFoo Post: 2 SenzaRef
  SetFoo Pre: 2 :: WithoutRef SetFoo
  Interno: 2 :: WithoutRef :: WithRef
  SetFoo Post: 2 WithoutRef :: WithRef

     

SetI Pre: 0 SetI Inside: 2 SetIPost: 0

     

SetRefI Pre: 0 SetRefI Interno: 3
  SetRefI Post: 3

Capisco ref con l'esempio intero ma non con l'esempio di iterazione di oggetti Foo sopra.

Grazie!

È stato utile?

Soluzione

Il riferimento viene passato per valore. Quindi il metodo può ancora cambiare il contenuto dell'oggetto, semplicemente non può cambiare a quale oggetto fa riferimento la tua variabile.

Vedi il mio articolo sul passaggio dei parametri per molte più informazioni, insieme al mio articolo su tipi di riferimento e tipi di valore .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top