Programiranje

Globok potop: Vrednosti in referenčne vrste v .Net

Vrste v Microsoft .Net so lahko bodisi vrsta vrednosti bodisi referenčna vrsta. Medtem ko se tipi vrednosti običajno shranijo v sklad, se referenčni tipi shranijo v upravljani kopici.

Tip vrednosti izhaja iz System.ValueType in vsebuje podatke znotraj lastne dodelitve pomnilnika. Z drugimi besedami, spremenljivke ali predmeti ali tipi vrednosti imajo svojo kopijo podatkov.

Referenčni tip medtem razširi System.Object in kaže na mesto v pomnilniku, ki vsebuje dejanske podatke. Lahko si predstavljate referenčni tip, podoben kazalcu, ki je implicitno razporejen, ko dostopate do njih. Vgrajeni referenčni tipi, ki jih podpira C #, vključujejo: objekt, niz in dinamiko. Vsi temeljni podatkovni tipi, logična vrednost, datum, zgradbe in naštevanja so primeri tipov vrednosti. Primeri referenčnih vrst vključujejo: nize, nize, predmete razredov itd. Če želite v C # ustvariti referenčne vrste, lahko izkoristite te ključne besede: razred, vmesnik in delegat.

Upoštevajte, da za razliko od referenčnega tipa ne morete izpeljati iz vrste vrednosti niti ne morete vrednosti tipa dodeliti neposredno vrednosti. Ničelni vrednosti lahko dodelite vrsto vrednosti samo tako, da izkoristite ničelne tipe - funkcijo, dodano novejšim različicam .Net Framework. Ko se vrsta vrednosti kopira v drugo, se vrednost kopira. Tako lahko vrednosti z njimi manipulirate neodvisno od druge - sprememba ene ne vpliva na drugo. Nasprotno, ko kopirate vrsto reference v drugo, se referenca kopira. Če spremenite enega od njih, to vpliva tudi na drugega. Na primer, če je ena referenca nastavljena na nič, tudi druga postane nična.

Prostori za shranjevanje

CLR predmete shranjuje na treh vrstah shranjevalnih mest - v registre, sklad ali upravljani kup. Medtem ko so kratkotrajni predmeti shranjeni znotraj registrov ali sklada, so dolgo živeči predmeti shranjeni v kopici. Kot sem že omenil, se vrste vrednosti običajno shranijo v sklad.

Pogosta napačna predstava je, da so vrste vrednosti vedno shranjene v skladu. Raje bi rekel, da tipi vrednosti lahko shranite v sklad, če je spremenljivka bodisi začasna spremenljivka bodisi lokalna spremenljivka in se JIT-ov prevajalnik odloči, da vrednosti ne bo registriral. V bistvu je dejanska lokacija vrste vrednosti odvisna od izvedbe prevajalnika JIT. Upoštevajte, da lahko vrsto vrednosti shranite v sklad sklada, v register CPU ali celo v pomnilnik kopice, če je vrsta vrednosti znotraj predmeta, tj. Če je del referenčnega tipa. Nasprotno, referenčni tipi so shranjeni v kopici GC. Sklic se shrani v sklad, medtem ko je predmet dodeljen na kopici.

Primerki ali sklici vrste vrednosti se shranijo v sklad, register ali na kopico, odvisno od tega, ali je življenjska doba primerka ali sklica kratkotrajna ali dolgotrajna. Vrsta vrednosti se lahko nahaja v skladišču, če gre za lokalne spremenljivke, in v upravljanem kupu, če gre za polja razreda, tj. Pripadajo ali so del referenčnega tipa.

Mimo vrednosti in mimo reference

Naslednji seznam kod ponazarja, kako lahko spremenljivko posredujete metodi po vrednosti.

 povečanje statične praznine (int i)

        {

i = i + 1;

        }

statična praznina Main ()

        {

int x = 1;

Prirastek (x);

Console.WriteLine ("Vrednost x je:" + x);

Console.Read ();

        }

Upoštevajte, da lahko vrsto vrednosti kot referenco na metodo posredujete z uporabo ključne besede ref. To ponazarja naslednji seznam kod.

povečanje statične praznine (ref int i)

        {

i = i + 1;

        }

statična praznina Main ()

        {

int x = 1;

Prirastek (ref x);

Console.WriteLine ("Vrednost x je:" + x);

Console.Read ();

        }

Ko se zgornja koda izvede, se v konzoli prikaže sporočilo "Vrednost x je: 2".

Boks in odpakiranje

Pretvorba vrste vrednosti v referenčno vrsto je znana kot boks. Razpakiranje je ravno nasprotno - definirano je kot postopek pretvorbe referenčnega tipa v vrednostni tip. Naslednji delček kode prikazuje boksanje in odpakiranje v C #.

int i = 100;

Predmet obj = i; // Boks

i = (int) obj; // Odpakiranje

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