Reference vs value types
Last updated
Last updated
OBS: Lite överkurs =)
Variabelnamn är egentligen bara namn på specifika minnesplatser i datorns RAM-minne.
Namnet något får kallas för en identifier.
Förenklat delas datorns minne upp i två delar: Stacken och heapen.
Stacken är strukturerad, snabb och begränsad i storlek. Det man lägger i den finns bara kvar så länge det nuvarande kodblocket körs.
Heapen är ostrukturerad, stor och det man lägger i den lever kvar tills det tas bort. I en del språk betyder det att man alltid måste komma ihåg att ta bort saker som ligger där manuellt – i C# och en del andra språk finns s.k. Garbage Collection som då och då rensar bort saker i heapen som det inte längre finns någon identifier som pekar mot.
Identifiers finns alltid i stacken. I stacken skapas en koppling mellan identifiern och vad den är satt att identifiera. Så till exempel skapas här en koppling mellan identifiern "x" och värdet "10".
För datatyper som är value types lagras också värdet i stacken. Int är ett exempel på value type. Så när int-variabeln t skapas så är det i stacken namnet "t" associeras med ett 32-bitar stort minnesutrymme.
Exempel på value types:
int, float och övriga numeriska typer.
bool
struct-typer
För datatyper som är reference types lagras själva objektet, datan, i heapen. Det enda som lagras på minnesadressen i stacken är en referens vidare till platsen i stacken där datan finns.
Så identifiern pekar på en plats i stacken, på den platsen finns en vidarepekning till en plats i heapen.
Value types och reference types beter sig olika när tilldelnings-operatorn = används. Mer exakt beter de sig exakt lika – men eftersom de lagrar olika saker i stacken så blir effekten olika.
Ovanstående gäller också parametrar i metoder.
Varning: Använd out och ref så lite som möjligt. Det är väldigt, väldigt lätt att göra fel med dem.
När en metod tar emot en parameter, är det i vanliga fall så att det man får en kopia av värdet i stacken.
Med out och ref kan man istället få en pekare till platsen i stacken – vilket gör att man inuti metoden kan ändra variabelns värden direkt.
Med andra ord – stoppar man in en variabel som ref eller out så får man vara beredd på att precis vad som helst kan ha hänt med den efteråt. Den kan ha fått ett helt nytt värde eller till och med, om det är en reference type-variabel, referera till ett helt annat objekt.
Ref och out fungerar i princip likadant, men det finns skillnader:
Med out måste variabeln initieras inuti metoden. Man kan alltså inte ändra ett existerande värde – variabeln som stoppas in kommer garanterat att ges ett helt annat värde i metoden.
Med ref måste variabeln redan vara initierad innan den stoppas in som ref. Man kan inte ref:a en variabel man skapar på plats. Med out kan man skapa variabeln i parenteserna vid anropet.