Programmering

Et dypdykk: Verdi- og referansetyper i .Net

Typer i Microsoft .Net kan være enten verditype eller referansetype. Mens verdityper lagres generelt i stabelen, lagres referansetyper i den administrerte dyngen.

En verditype kommer fra System.ValueType og inneholder dataene i sin egen minnetildeling. Med andre ord, variabler eller objekter eller verdityper har sin egen kopi av dataene.

En referansetype utvider i mellomtiden System.Object og peker på et sted i minnet som inneholder de faktiske dataene. Du kan forestille deg en referansetype som ligner på en peker som implisitt blir referert når du får tilgang til dem. De innebygde referansetypene som støttes av C # inkluderer: objekt, streng og dynamisk. Alle grunnleggende datatyper, boolsk, dato, strukturer og enums er eksempler på verdityper. Eksempler på referansetyper inkluderer: strenger, matriser, objekter fra klasser osv. For å lage referansetyper i C # kan du dra nytte av disse nøkkelordene: klasse, grensesnitt og delegat.

Merk at i motsetning til en referansetype, kan du ikke stamme fra en verditype, og du kan heller ikke tildele en nullverdi direkte til en verditype. Du kan bare tilordne en nullverdi til en verditype ved å dra nytte av nullbare typer - en funksjon som er lagt til i de nyere versjonene av .Net Framework. Når en verditype kopieres til en annen, kopieres verdien. Derfor kan du manipulere verdiene i dem uavhengig av den andre - en endring i den ene påvirker ikke den andre. Tvert imot, når du kopierer en referansetype til en annen, blir referansen kopiert. Hvis du endrer en av dem, blir den andre også berørt. For eksempel, hvis en av referansen er satt til null, blir den andre også null.

Oppbevaringssteder

CLR lagrer objekter på tre typer lagringssteder - registerene, stakken eller den administrerte dyngen. Mens de kortvarige gjenstandene lagres i registre eller stabler, lagres de langlivede objektene i dyngen. Som jeg nevnte tidligere, lagres verdityper generelt i stabelen.

Det er en vanlig misforståelse at verdityper alltid er lagret i stabelen. Jeg vil heller si at verdityper kan lagres i stabelen når variabelen enten er en midlertidig variabel eller er en lokal variabel, og JIT-kompilatoren bestemmer seg for ikke å registrere verdien. I virkeligheten avhenger den faktiske plasseringen av en verditype av implementeringen av JIT-kompilatoren. Merk at en verditype kan lagres i en stabelramme, i CPU-registeret eller til og med i heapminnet hvis verditypen er inneholdt i et objekt, dvs. hvis det er en del av en referansetype. Tvert imot lagres referansetyper i GC-bunken. Referansen lagres i en bunke mens objektet tildeles i dyngen.

Forekomster eller referanser av en verditype lagres i stabelen, registeret eller i bunken, avhengig av om levetiden til forekomsten eller referansen er kortvarig eller langvarig. En verditype kan ligge på stakken hvis de er lokale variabler og i den administrerte bunken hvis de er felt i en klasse, dvs. de tilhører eller er en del av en referansetype.

Passer etter verdi og passerer ved referanse

Følgende kodeliste illustrerer hvordan du kan overføre en variabel til en metode etter verdi.

 statisk tomrom Increment (int i)

        {

i = i + 1;

        }

statisk tomrom Main ()

        {

int x = 1;

Inkrement (x);

Console.WriteLine ("Verdien av x er:" + x);

Console.Read ();

        }

Merk at du kan sende en verditype som referanse til en metode ved å bruke ref-nøkkelordet. Følgende kodeliste illustrerer dette.

statisk tomrom Increment (ref int i)

        {

i = i + 1;

        }

statisk tomrom Main ()

        {

int x = 1;

Inkrement (ref x);

Console.WriteLine ("Verdien av x er:" + x);

Console.Read ();

        }

Når koden ovenfor kjøres, vises meldingen "Verdien av x er: 2" i konsollen.

Boksing og unboksing

Konvertering av en verditype til en referansetype er kjent som boksing. Unboxing er akkurat det motsatte - det er definert som prosessen med konvertering av en referansetype til en verditype. Følgende kodebit illustrerer boksing og unboxing i C #.

int i = 100;

Objekt obj = i; // Boksing

i = (int) obj; // Unboxing

$config[zx-auto] not found$config[zx-overlay] not found