Programovanie

Hlboký ponor: typy hodnôt a referencií v .Net

Typy v sieti Microsoft .Net môžu byť buď hodnotový typ, alebo referenčný typ. Zatiaľ čo typy hodnôt sú všeobecne uložené v zásobníku, referenčné typy sú uložené v spravovanej halde.

Typ hodnoty je odvodený od System.ValueType a obsahuje údaje vo vnútri jeho vlastnej alokácie pamäte. Inými slovami, premenné alebo objekty alebo typy hodnôt majú svoju vlastnú kópiu údajov.

Referenčný typ medzitým rozširuje System.Object a ukazuje na miesto v pamäti, ktoré obsahuje skutočné údaje. Môžete si predstaviť referenčný typ podobný ukazovateľu, ktorý je implicitne dereferencovaný, keď k nim získate prístup. Medzi vstavané referenčné typy podporované C # patria: object, string a dynamic. Príklady typov hodnôt sú všetky základné dátové typy, Boolean, Date, structs a enums. Medzi príklady referenčných typov patria: reťazce, polia, objekty tried atď. Ak chcete v C # vytvoriť referenčné typy, môžete využiť výhody týchto kľúčových slov: class, interface and delegate.

Všimnite si, že na rozdiel od referenčného typu nemôžete odvodiť od typu hodnoty, ani nemôžete priradiť nulovú hodnotu priamo k typu hodnoty. Hodnotu null môžete priradiť typu hodnoty iba pomocou výhod typov s možnou hodnotou null - funkcie pridanej k novším verziám rozhrania .Net Framework. Keď sa typ hodnoty skopíruje do iného, ​​hodnota sa skopíruje. Preto môžete manipulovať s hodnotami v nich nezávisle na druhom - zmena v jednej neovplyvní druhú. Naopak, pri kopírovaní typu odkazu do iného sa referencia skopíruje. Ak zmeníte jednu z nich, ovplyvní to aj druhú. Napríklad ak je jeden z odkazov nastavený na hodnotu null, druhý sa tiež stane nulovým.

Skladovacie miesta

CLR ukladá objekty do troch typov ukladacích miest - registrov, zásobníka alebo spravovanej haldy. Zatiaľ čo objekty s krátkou životnosťou sú uložené vo vnútri registrov alebo stohu, objekty s dlhou životnosťou sú uložené v halde. Ako som už spomínal, typy hodnôt sa všeobecne ukladajú do zásobníka.

Je bežnou mylnou predstavou, že typy hodnôt sú vždy uložené v zásobníku. Skôr by som povedal, že hodnotové typy môcť byť uložené v zásobníku, keď je premenná buď dočasná, alebo lokálna, a kompilátor JIT sa rozhodne hodnotu neregistrovať. Skutočné umiestnenie hodnotového typu v podstate závisí od implementácie kompilátora JIT. Všimnite si, že typ hodnoty je možné uložiť v rámci stohu, v registri CPU alebo dokonca v halde, ak je typ hodnoty obsiahnutý vo vnútri objektu, t. J. Ak je súčasťou referenčného typu. Naopak, referenčné typy sú uložené v halde GC. Referencia je uložená v zásobníku, zatiaľ čo objekt je alokovaný v halde.

Inštancie alebo referencie typu hodnoty sú uložené v zásobníku, registri alebo na halde podľa toho, či je životnosť inštancie alebo referencie krátkodobá alebo dlhodobá. Typ hodnoty sa môže nachádzať v zásobníku, ak ide o lokálne premenné, a na spravovanej halde, ak ide o polia triedy, t. J. Patrí alebo je súčasťou referenčného typu.

Predávanie hodnotou a odovzdávanie referencie

Nasledujúci zoznam kódov ilustruje, ako môžete premennej odovzdať metódu podľa hodnoty.

 statický void prírastok (int i)

        {

i = i + 1;

        }

static void Main ()

        {

int x = 1;

Prírastok (x);

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

Console.Read ();

        }

Upozorňujeme, že typ hodnoty môžete odovzdať ako odkaz na metódu pomocou kľúčového slova ref. Nasledujúci zoznam kódov to ilustruje.

statický void prírastok (ref int i)

        {

i = i + 1;

        }

static void Main ()

        {

int x = 1;

Prírastok (ref x);

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

Console.Read ();

        }

Po vykonaní vyššie uvedeného kódu sa na konzole zobrazí správa „Hodnota x je: 2“.

Škatuľka a rozbalenie

Konverzia typu hodnoty na referenčný typ sa nazýva box. Rozbalenie je pravý opak - definuje sa ako proces prevodu referenčného typu na hodnotový typ. Nasledujúci úryvok kódu ilustruje box a unboxing v C #.

int i = 100;

Objekt obj = i; // Box

i = (int) obj; //Rozbaľovanie

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