Cvičení – zjišťování referenčních typů
- 8 min
Odkazové typy zahrnují pole, třídy a řetězce. Odkazové typy se zpracovávají odlišně od hodnotových typů, které se týkají způsobu ukládání hodnot při provádění aplikace.
V tomto cvičení se dozvíte, jak se odkazové typy liší od typů hodnot a jak pomocí operátoru new přidružit proměnnou k hodnotě v paměti počítače.
Jak se odkazové typy liší od hodnotových typů
Proměnná typu hodnoty ukládá své hodnoty přímo do oblasti úložiště označované jako zásobník. Zásobník je paměť přidělená kódu, který aktuálně běží na procesoru (označuje se také jako blok zásobníku nebo aktivační blok). Jakmile se dokončí provádění bloku zásobníku, hodnoty v zásobníku se odeberou.
Proměnná typu odkazu ukládá své hodnoty do samostatné oblasti paměti označované jako halda. Halda je oblast paměti, kterou sdílí řada aplikací spuštěných současně v operačním systému. Modul runtime .NET komunikuje s operačním systémem, aby určil, jaké adresy paměti jsou k dispozici, a požádá o adresu, kam může hodnotu uložit. Modul runtime .NET hodnotu uloží a pak vrátí adresu paměti do proměnné. Když kód použije tuto proměnnou, modul runtime .NET jednoduše vyhledá adresu uloženou v proměnné a načte hodnotu, která je tam uložená.
Dále napíšete nějaký kód, který tyto myšlenky jasněji ilustruje.
Definování proměnné typu odkazu
Odstraňte nebo použijte operátor
//komentáře řádku k zakomentování veškerého kódu z předchozích cvičení.Následujícím způsobem aktualizujte kód v editoru visual Studio Code:
int[] data;Předchozí kód definuje proměnnou, která může obsahovat hodnotu pole typu
int.V tuto chvíli je
datapouze proměnná, která by mohla obsahovat odkaz, nebo spíše adresu paměti hodnoty v haldě. Vzhledem k tomu, že neukazuje na adresu paměti, nazývá se nulový odkaz.Vytvoření instance pole pomocí klíčového
intnewslovaAktualizujte kód v editoru editoru visual Studio Code tak, aby vytvořil a přiřadil novou instanci
intpole pomocí následujícího kódu:int[] data; data = new int[3];Klíčové
newslovo informuje modul runtime .NET, aby vytvořil instanciintpole, a pak koordinuje s operačním systémem pro uložení velikosti pole pro tři int hodnoty v paměti. Modul runtime .NET vyhoví a vrátí adresu paměti nového poleint. Nakonec se adresa paměti uloží v datech proměnné. Prvky poleintjsou standardně nastavené na hodnotu0, protože se jedná o výchozí hodnotu typuint.Upravte příklad kódu tak, aby prováděl obě operace v jednom řádku kódu.
Dva řádky kódu v předchozím kroku se obvykle zkracují na jeden řádek kódu, který deklaruje proměnnou, a vytvoří novou instanci
intpole. Upravte kód z kroku 3 tak, aby odpovídal následujícímu kódu.int[] data = new int[3];I když neexistuje žádný výstup, který by bylo možné sledovat, snad toto cvičení přidalo přehled o tom, jak syntaxe jazyka C# souvisí s kroky procesu pro práci s odkazovými typy.
Co se liší od datového typu řetězce jazyka C#?
Datový typ string je také odkazový typ. Možná vás zajímá, proč new se operátor při deklarování řetězce nepoužil. Je to čistě z pohodlnosti, kterou si můžeme dovolit díky návrhářům jazyka C#. Vzhledem k tomu, že se string datový typ používá tak často, můžete použít tento formát:
string shortenedString = "Hello World!";
Console.WriteLine(shortenedString);
Na pozadí se ale vytvoří nová instance System.String a inicializuje se na "Hello World!".
Praktické aspekty používání hodnot a referenčních typů
-
Typ hodnoty (int): V tomto příkladu
val_Aval_Bjsou celočíselné typy hodnot.
int val_A = 2;
int val_B = val_A;
val_B = 5;
Console.WriteLine("--Value Types--");
Console.WriteLine($"val_A: {val_A}");
Console.WriteLine($"val_B: {val_B}");
Měl by se zobrazit následující výstup:
--Value Types--
val_A: 2
val_B: 5
Při val_B = val_A spuštění je hodnota val_A zkopírována a uložena v val_B. Takže když val_B se změní, val_A zůstane nedotčený.
-
Typ odkazu (matice): V tomto příkladu
ref_Ajsouref_Bodkazové typy matice.
int[] ref_A= new int[1];
ref_A[0] = 2;
int[] ref_B = ref_A;
ref_B[0] = 5;
Console.WriteLine("--Reference Types--");
Console.WriteLine($"ref_A[0]: {ref_A[0]}");
Console.WriteLine($"ref_B[0]: {ref_B[0]}");
Měl by se zobrazit následující výstup:
--Reference Types--
ref_A[0]: 5
ref_B[0]: 5
Při ref_B = ref_A spuštění ref_B odkazuje na stejné umístění paměti jako ref_A.
ref_B[0] Při změně se tedy také změní, ref_A[0] protože oba odkazují na stejné umístění paměti. Jedná se o klíčový rozdíl mezi typy hodnot a odkazovými typy.
Rekapitulace
- Hodnotové typy mohou obsahovat menší hodnoty a ukládají se do zásobníku. Odkazové typy mohou obsahovat velké hodnoty a nová instance odkazového typu se vytvoří pomocí operátoru
new. Proměnné odkazového typu obsahují odkaz (adresu paměti) na skutečnou hodnotu uloženou v haldě. - Odkazové typy zahrnují pole, řetězce a třídy.