Passando per ref e fuori
-
10-07-2019 - |
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 :: WithRefSetFoo Pre: 2 SetFoo Interno: 2 ::
WithoutRef SetFoo Post: 2 SenzaRef
SetFoo Pre: 2 :: WithoutRef SetFoo
Interno: 2 :: WithoutRef :: WithRef
SetFoo Post: 2 WithoutRef :: WithRefSetI 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!
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 .