Ho intenzione di cimentarmi in una spiegazione:
Penso che capiamo come funzionano i tipi di valore? I tipi di valore sono (int, long, struct ecc.). Quando li invii a una funzione senza un comando ref, COPIA i dati . Qualunque cosa tu faccia a quei dati nella funzione ha effetto solo sulla copia, non sull'originale. Il comando ref invia i dati EFFETTIVI e qualsiasi modifica influirà sui dati esterni alla funzione.
Ok per la parte confusa, tipi di riferimento:
Consente di creare un tipo di riferimento:
List<string> someobject = new List<string>()
Quando si rinnova un oggetto , vengono create due parti:
- Il blocco di memoria che contiene i dati per qualche oggetto .
- Un riferimento (puntatore) a quel blocco di dati.
Ora, quando si invia un oggetto in un metodo senza ref, COPIA il puntatore di riferimento , NON i dati. Quindi ora hai questo:
(outside method) reference1 => someobject
(inside method) reference2 => someobject
Due riferimenti che puntano allo stesso oggetto. Se modifichi una proprietà su qualche oggetto usando reference2, questo influenzerà gli stessi dati a cui fa riferimento reference1.
(inside method) reference2.Add("SomeString");
(outside method) reference1[0] == "SomeString" //this is true
Se annulli riferimento2 o lo punti a nuovi dati, ciò non influirà su riferimento1 né su riferimento1.
(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true
The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject
Cosa succede quando si invia un oggetto tramite ref a un metodo? Il riferimento effettivo a someobject viene inviato al metodo. Quindi ora hai un solo riferimento ai dati:
(outside method) reference1 => someobject;
(inside method) reference1 => someobject;
Ma cosa significa? Agisce esattamente come inviare un oggetto non per ref, tranne per due cose principali:
1) Quando annulli il riferimento all'interno del metodo, questo annullerà quello esterno al metodo.
(inside method) reference1 = null;
(outside method) reference1 == null; //true
2) Ora è possibile puntare il riferimento a una posizione dei dati completamente diversa e il riferimento esterno alla funzione ora punta alla nuova posizione dei dati.
(inside method) reference1 = new List<string>();
(outside method) reference1.Count == 0; //this is true
MyClass
unclass
tipo, cioè un tipo di riferimento. In tal caso, l'oggetto che passi può essere modificatomyFunction
anche da noref
/out
parola chiave.myFunction
riceverà un nuovo riferimento che punta allo stesso oggetto e può modificare lo stesso oggetto quanto vuole. La differenza cheref
farebbe la parola chiave sarebbe che hamyFunction
ricevuto lo stesso riferimento allo stesso oggetto. Ciò sarebbe importante solo semyFunction
cambiassi il riferimento per puntare a un altro oggetto.