Ćwiczenie — odnajdywanie typów referencyjnych
- {liczbaMinut} minut
Typy referencyjne obejmują tablice, klasy i ciągi. Typy referencyjne są traktowane inaczej niż typy wartości dotyczące sposobu przechowywania wartości podczas wykonywania aplikacji.
W tym ćwiczeniu dowiesz się, jak typy referencyjne różnią się od typów wartości i jak używać new operatora do skojarzenia zmiennej z wartością w pamięci komputera.
Czym różnią się typy referencyjne od typów wartości
Zmienna typu wartości przechowuje swoje wartości bezpośrednio w obszarze magazynu nazywanym stosem. Stos to pamięć przydzielona do kodu, który jest aktualnie uruchomiony na procesorze CPU (można też spotkać się z nazwami ramka stosu lub ramka aktywacji). Po zakończeniu wykonywania ramki stosu wartości są usuwane ze stosu.
Zmienna typu odwołania przechowuje swoje wartości w osobnym regionie pamięci nazywanym stertą. Sterta to obszar pamięci, który jest współużytkowany przez wiele aplikacji działających w systemie operacyjnym w tym samym czasie. Środowisko uruchomieniowe platformy .NET komunikuje się z systemem operacyjnym w celu określenia, które adresy pamięci są dostępne, i żąda adresu, w którym może przechować wartość. Środowisko uruchomieniowe platformy .NET zapisuje wartość, a następnie zwraca adres pamięci do zmiennej. Gdy kod używa zmiennej, środowisko uruchomieniowe platformy .NET automatycznie wyszukuje adres zapisany w zmiennej i pobiera wartość przechowywaną w tym miejscu.
Następnie napiszesz kod, który zilustruje te pomysły bardziej wyraźnie.
Definiowanie zmiennej typu odwołania
Usuń lub użyj operatora
//komentarza wiersza, aby oznaczyć jako komentarz cały kod z poprzednich ćwiczeń.Zaktualizuj kod w edytorze programu Visual Studio Code w następujący sposób:
int[] data;Poprzedni kod definiuje zmienną, która może przechowywać wartość tablicy typów
int.Na tym etapie
datajest tylko zmienną, która może przechowywać odwołanie lub raczej adres pamięci dla wartości w stercie. Ponieważ nie wskazuje ona adresu pamięci, jest nazywana nullowym odwołaniem.Tworzenie wystąpienia tablicy
intprzy użyciu słowa kluczowegonewZaktualizuj kod w edytorze programu Visual Studio Code, aby utworzyć i przypisać nowe wystąpienie tablicy
intprzy użyciu następującego kodu:int[] data; data = new int[3];Słowo
newkluczowe informuje środowisko uruchomieniowe platformy .NET o utworzeniuintwystąpienia tablicy, a następnie koordynowanie z systemem operacyjnym przechowywania tablicy o rozmiarze trzech wartości int w pamięci. Środowisko uruchomieniowe platformy .NET uzgadnia i zwraca adres pamięci nowej tablicy typuint. Na koniec adres pamięci jest przechowywany w danych zmiennej. Elementy tablicy typuintmają wartości domyślne0, ponieważ jest to wartość domyślna typuint.Modyfikowanie przykładu kodu w celu wykonania obu operacji w jednym wierszu kodu
Dwa wiersze kodu w poprzednim kroku są zwykle skracane do jednego wiersza kodu, aby zadeklarować zmienną i utworzyć nowe wystąpienie
inttablicy. Zmodyfikuj kod z kroku 3, aby wyglądał jak ten poniżej.int[] data = new int[3];Chociaż nie ma żadnych danych wyjściowych do obserwowania, miejmy nadzieję, że to ćwiczenie zwiększa przejrzystość sposobu, w jaki składnia języka C# odnosi się do kroków procesu pracy z typami referencyjnymi.
Co różni się od typu danych ciągu języka C#?
Typ danych string jest również typem referencyjnym. Być może zastanawiasz się, dlaczego new operator nie był używany podczas deklarowania ciągu. Jest to po prostu ułatwienie wprowadzone dzięki projektantom języka C#.
string Ponieważ typ danych jest używany tak często, można użyć następującego formatu:
string shortenedString = "Hello World!";
Console.WriteLine(shortenedString);
Jednak za kulisami tworzone jest nowe wystąpienie programu System.String i inicjowane na "Hello World!".
Praktyczne zagadnienia związane z używaniem wartości i typów referencyjnych
-
Typ wartości (int): w tym przykładzie
val_Aival_Bsą typami wartości całkowitych.
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}");
Powinny zostać wyświetlone następujące dane wyjściowe:
--Value Types--
val_A: 2
val_B: 5
Po val_B = val_A wykonaniu val_A wartość jest kopiowana i przechowywana w pliku val_B. W związku z tym, gdy val_B zostanie zmieniona, val_A pozostaje nienaruszona.
-
Typ odwołania (tablica): w tym przykładzie
ref_Airef_Bsą typami odwołania do tablicy.
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]}");
Powinny zostać wyświetlone następujące dane wyjściowe:
--Reference Types--
ref_A[0]: 5
ref_B[0]: 5
Po ref_B = ref_A wykonaniu ref_B wskazuje tę samą lokalizację pamięci co ref_A. Dlatego po ref_B[0] zmianie zmienia się również, ref_A[0] ponieważ obie wskazują tę samą lokalizację pamięci. Jest to kluczowa różnica między typami wartości i typami referencyjnymi.
Podsumowanie
- Typy wartości mogą przechowywać mniejsze wartości i są zapisywane na stosie. Typy referencyjne mogą przechowywać duże wartości, a nowe wystąpienie typu referencyjnego jest tworzone za pomocą operatora
new. Zmienne typu referencyjnego przechowują odwołanie (adres pamięci) do rzeczywistej wartości zapisanej w stercie. - Typy referencyjne obejmują tablice, ciągi i klasy.
Sprawdź swoją wiedzę
Opinia
Czy ta strona była pomocna?
Nie
Potrzebujesz pomocy dotyczącej tego tematu?
Chcesz spróbować użyć asystenta Ask Learn, aby wyjaśnić ten temat lub uzyskać instrukcje, które go dotyczą?