.NET Framework
Stack and Heap
Szukaj…
Uwagi
Warto zauważyć, że przy deklarowaniu typu odniesienia jego wartość początkowa będzie null
. Wynika to z faktu, że nie wskazuje on jeszcze lokalizacji w pamięci i jest stanem całkowicie poprawnym.
Jednak z wyjątkiem typów dopuszczających wartości zerowe typy wartości zazwyczaj muszą zawsze mieć wartość.
Typy wartości w użyciu
Typy wartości zawierają po prostu wartość .
Wszystkie typy wartości pochodzą z klasy System.ValueType , a to obejmuje większość typów wbudowanych.
Podczas tworzenia nowego typu wartości wykorzystywany jest obszar pamięci zwany stosem .
Stos odpowiednio wzrośnie o rozmiar deklarowanego typu. Na przykład int zawsze będzie miał przydzielone 32 bity pamięci na stosie. Gdy typ wartości nie jest już objęty zakresem, miejsce na stosie zostanie zwolnione.
Poniższy kod pokazuje typ wartości przypisany do nowej zmiennej. Struktura jest używana jako wygodny sposób tworzenia niestandardowego typu wartości (klasy System.ValueType nie można w inny sposób rozszerzyć).
Ważną rzeczą do zrozumienia jest to, że przy przypisywaniu typu wartości sama wartość jest kopiowana do nowej zmiennej, co oznacza, że mamy dwa różne wystąpienia obiektu, które nie mogą na siebie wpływać.
struct PersonAsValueType
{
public string Name;
}
class Program
{
static void Main()
{
PersonAsValueType personA;
personA.Name = "Bob";
var personB = personA;
personA.Name = "Linda";
Console.WriteLine( // Outputs 'False' - because
object.ReferenceEquals( // personA and personB are referencing
personA, // different areas of memory
personB));
Console.WriteLine(personA.Name); // Outputs 'Linda'
Console.WriteLine(personB.Name); // Outputs 'Bob'
}
}
Typy referencyjne w użyciu
Typy referencyjne obejmują zarówno odwołanie do obszaru pamięci, jak i wartość przechowywaną w tym obszarze.
Jest to analogiczne do wskaźników w C / C ++.
Wszystkie typy referencji są przechowywane na tak zwanej stercie .
Sterta to po prostu zarządzany obszar pamięci, w którym przechowywane są obiekty. Po utworzeniu instancji nowego obiektu część sterty zostanie przydzielona do użycia przez ten obiekt, a odwołanie do tej lokalizacji sterty zostanie zwrócone. Sterta jest zarządzana i utrzymywana przez moduł wyrzucania elementów bezużytecznych i nie umożliwia ręcznej interwencji.
Oprócz miejsca w pamięci wymaganego dla samej instancji wymagana jest dodatkowa przestrzeń do przechowywania samego odwołania, a także dodatkowe informacje tymczasowe wymagane przez CLR .NET.
Poniższy kod pokazuje typ odniesienia przypisany do nowej zmiennej. W tym przypadku używamy klasy, wszystkie klasy są typami referencyjnymi (nawet jeśli są statyczne).
Gdy typ odniesienia jest przypisany do innej zmiennej, to jest to odwołanie do obiektu, który jest kopiowany, a nie sama wartość. Jest to ważne rozróżnienie między typami wartości a typami odniesienia.
Konsekwencją tego jest to, że mamy teraz dwa odniesienia do tego samego obiektu.
Wszelkie zmiany wartości w tym obiekcie zostaną odzwierciedlone przez obie zmienne.
class PersonAsReferenceType
{
public string Name;
}
class Program
{
static void Main()
{
PersonAsReferenceType personA;
personA = new PersonAsReferenceType { Name = "Bob" };
var personB = personA;
personA.Name = "Linda";
Console.WriteLine( // Outputs 'True' - because
object.ReferenceEquals( // personA and personB are referencing
personA, // the *same* memory location
personB));
Console.WriteLine(personA.Name); // Outputs 'Linda'
Console.WriteLine(personB.Name); // Outputs 'Linda'
}