Potrzebujesz interpretacji sekcji w specyfikacji C #

11

Czytam specyfikację C # . Przydałoby mi się wyjaśnienie dotyczące segmentu:

C # ma zunifikowany system typów. Wszystkie typy C #, w tym typy pierwotne, takie jak int i double, dziedziczą po jednym typie obiektu głównego. W ten sposób wszystkie typy mają wspólny zestaw operacji, a wartości dowolnego typu mogą być przechowywane, transportowane i obsługiwane w spójny sposób. Ponadto C # obsługuje zarówno typy referencyjne zdefiniowane przez użytkownika, jak i typy wartości, umożliwiając dynamiczne przydzielanie obiektów, a także przechowywanie w linii lekkich struktur.

Co w tym kontekście oznacza „przechowywanie lekkich konstrukcji w linii”?

ChuckT
źródło

Odpowiedzi:

11

Odpowiedź Svicka jest dobra, ale pomyślałem, że dodam kilka dodatkowych punktów.

Po pierwsze, akapit jest wadliwy. Typy wskaźników nie dziedziczą po obiekcie. Wartości, które są w czasie kompilacji znane jako typy interfejsów lub typy parametrów typów, w czasie wykonywania będą albo niepoprawnymi referencjami, albo autentycznymi instancjami czegoś, co dziedziczy po obiekcie, ale zawsze dziwnie było mi powiedzieć, że te typy „ odziedziczyć "po obiekcie; Dziedziczenie jest właściwością, że członkowie przodka są członkami potomka, ale zwykle nie myślisz o „ToString” jako o członku IEnumerable. Myślicie o tym jako o członku implementującym IEnumerable .

Akapit jest również wadliwy, ponieważ jest to jedyne miejsce, w którym „typ pierwotny” pojawia się w specyfikacji i pojawia się bez definicji. Jest to zatem niepotrzebne i mylące i powinno zostać usunięte.

Chciałem, aby ten akapit został przez jakiś czas naprawiony. Następnym razem, gdy zobaczę Madsa, przypomnę mu.

Aby odpowiedzieć na konkretne pytanie: svick jest oczywiście poprawny, ale warto zobaczyć konkretny przykład. Kiedy powiesz:

struct ColorfulInt
{
    int value;
    Color color;
    ...
}

i tworzysz, powiedzmy, tablicę:

ColorfulInt[] x = new ColorFulInt[100];

Następnie pamięć dla tych 100 liczb wewnętrznych i 100 kolorów przechodzi do samej tablicy . Gdyby zamiast tego ColorfulInt była tablica, tablica zawierałaby 100 odwołań do ColorfulInt, z których każde musiałoby być przydzielone indywidualnie. Indywidualne przydzielanie tych stu elementów jest znacznie mniej wydajne zarówno pod względem czasu, jak i przestrzeni niż zwykłe przydzielanie pamięci bezpośrednio w samej tablicy.

Eric Lippert
źródło
Czy więc znaczenie w abstrakcjach pamięci tych obiektów jest łatwiejsze, gdy jesteś gotowy nimi manipulować, jeśli są one w jednym ciągłym bloku adresowalnych wersetów przestrzeni, które wskazują, kto wie gdzie? Czy to prawda, czy wciąż czegoś mi brakuje?
ChuckT,
@ChuckT: Poprawnie. Nie ponosisz kosztów pośrednich, a także zyskujesz dobrą lokalizację pamięci podręcznej.
Eric Lippert,
12

Oznacza to, że typy wartości są przechowywane bezpośrednio tam, gdzie je definiujesz, co czyni je bardziej wydajnymi w porównaniu z typami referencyjnymi.

Co to dokładnie znaczy? Jeśli masz zmienną lokalną typu wartości, zwykle będzie ona przechowywana bezpośrednio na stosie (ale istnieje wiele wyjątków). Jeśli masz pole typu wartości, zostanie ono zapisane bezpośrednio w otaczającej klasie lub strukturze.

svick
źródło
1
To ma sens. Dzięki, że mi to przesłałeś, sickick!
ChuckT