2012-10-16 16 views
7

Mam problem ze zrozumieniem reprezentacji typów wartości w .NET. Każdy typ wartości pochodzi z klasy System.ValueType, więc czy oznacza to, że Typ wartości jest klasą?Jak działają typy wartości w .NET?

Na przykład, jeśli mogę napisać:

int x = 5; 

oznacza to, że tworzę instancję System.Int32 klasy za”napisać to w zmiennej x ??

+1

[System.ValueType] (http://msdn.microsoft.com/ en-us/library/system.valuetype.aspx) – Oded

+2

_derived from System.ValueType class_ Jest to szczególna forma czerpania, nie taka sama jak dziedziczenie. Jest wbudowany w Fx. –

+2

Dla przyszłych czytelników: [** Prawda o typach wartości **] (http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value- typeses.aspx) –

Odpowiedz

6

Klasa System.ValueType jest po prostu klasą "meta", a wewnętrzna jest obsługiwana inaczej niż w przypadku klas normalnych. Struktury i prymitywne typy dziedziczą niejawnie System.ValueType, ale ten typ faktycznie nie istnieje w czasie wykonywania, jest to po prostu sposób, w jaki zespoły zaznaczają, że klasa powinna być traktowana jak struktura typu wartości i przyjmować semantykę typu "wartość po wartości".

W przeciwieństwie do innych odpowiedzi, typy wartości nie zawsze są przydzielane na stosie. Gdy są to pola w klasie, są umieszczane na stercie, tak jak pozostałe dane klasy, gdy ten obiekt jest tworzony. Zmienne lokalne można również wciągnąć do niejawnej klasy, gdy są używane w iteratorach lub zamknięciach.

+0

dziękuję, bardzo pomocne –

-1

Typy wartości nie są klasami. Są one wbudowane w językach i są obsługiwane przez .NET CTS (Common Type System). CTS jest składnikiem wewnątrz CLR, który jest odpowiedzialny za obsługę typów wartości, takich jak bool, int, double, float itp. Po utworzeniu obiektu typu wartości tworzony jest on na stosie. Po przekazaniu go do funkcji lub zwrocie z funkcji tworzony jest nowy obiekt w pamięci RAM. Ale w przypadku typów referencyjnych przekazywane jest tylko odniesienie do obiektu, a nowy obiekt nie jest tworzony w pamięci. Istnieje kilka typów wartości zdefiniowanych przez użytkownika, które nie są w specyfikacji językowej i są zdefiniowane przez użytkowników. Takie typy wartości są dziedziczone z System.ValueType. Przykładem tego rodzaju wartości jest liczba zespolona. Możemy stworzyć własny, zdefiniowany przez użytkownika typ liczb zespolonych, używając System.ValueType.

+0

Nie zamierzam przegłosować, ponieważ jest to twój pierwszy dzień na SO, ale proszę przeczytaj komentarze innej odpowiedzi –

+1

Zamierzam zgodzić się, ponieważ jest źle. Zobacz http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx, aby dokładnie przeanalizować typy wartości. –

+0

@ThomSmith: Chociaż stos jest szczegółem implementacji, podstawowy punkt jest poprawny: miejsca przechowywania typu wartości (w tym tymczasowe kompilatory) nie przechowują obiektów klas. Specyfikacja C# może twierdzić, że zawartość pola 'Int32' dziedziczy po' System.Object', ale specyfikacja CLI (która opisuje, jak świat kodu zarządzanego faktycznie działa) sprawia, że ​​'System.Int32' opisuje dwa typy: typ obiektu sterty, który pochodzi od 'System.Object' i typ miejsca przechowywania, który nie jest obiektem. Specyfikacja C# może udawać, że jest inaczej, ale to nie czyni prawdy. – supercat

0

Teraz dużo o tym mówić. Poważnie, jest tu setki stron na ten temat w sieci, a większość z nich spala moją mózgową sprawę w alarmującym tempie.

To, co właściwie pamiętałem, to to, że int i Int32 to to samo, a obie działają jak struktura, a nie klasa. "int" jest skrótem do Int32. (Jeśli umieścisz kursor myszy nad int, tooltip brzmi "struct System.Int32" Co oznacza:..

public class BoxedInt 
{ 
    public int x; 

    public BoxedInt(int i) { x = i; } 
} 

public Test() 
{ 
    BoxedInt bi = new BoxedInt(10); 
    Boxed(bi); 
    Console.WriteLine(bi.x); // Returns 11, as any reference type would. 

    int vi = 10; 
    Valued(vi); 
    Console.WriteLine(vi); // Returns 10, because it acts like a struct. (Which it is) 
} 

public void Boxed(BoxedInt i) 
{ 
    i.x++; 
} 

public void Valued(int i) 
{ 
    i++; 
} 
+0

'public void Valued (ref int i)' zwróci 11, ponieważ ...? – AgentFire

+0

Zwroty w pudełku 11, Zwroty wartości 10. – LightStriker

+0

Wartość w pudełku lub, jeśli wolisz, wartość zawarta w klasie jest jak w pudełku. Jeśli powiem ci, gdzie jest pudełko i zmienisz jego zawartość, mogę sprawdzić to pole i zobaczyć, co zmieniłeś. W tym celu klasa działa jak pudełko i będzie istnieć tak długo, jak gdzieś w kodzie odwoła się do niego. Jeśli chodzi o normalną wartość, mogę powiedzieć ci tę wartość, ale nie mogę ci jej dać. Jeśli zdecydujesz, że to powinno się zmienić, nie mogę tego wiedzieć, chyba że wyraźnie mi powiesz. W tym celu "i" istnieje tylko w granicach metody Valued i jest niszczone zaraz po zakończeniu metody. – LightStriker

1

Zobacz Eric Lippert's article

w skrócie, typ wartości jest kopiowany przez wartość Value. typy są klasami podobnie jak typy odwołań, a instancje typów wartości są obiektami: 5 to obiekt, instancja o nazwie System.Int32 (int w skrócie)

Powiązane problemy