Wygląda na to, że każda książka .NET mówi o typach wartości vs typach referencyjnych i wskazuje na (często niepoprawnie) stan, w którym każdy typ jest przechowywany - sterty lub stosu. Zwykle znajduje się w kilku pierwszych rozdziałach i jest przedstawiany jako bardzo ważny fakt.
Zgadzam się całkowicie; Cały czas to widzę.
Dlaczego książki .NET mówią o alokacji pamięci stosu a sterty?
Jednym z powodów jest to, że wiele osób przyszło do C # (lub innych języków .NET) z tła C lub C ++. Ponieważ te języki nie egzekwują reguł dotyczących okresu przechowywania, musisz znać te reguły i dokładnie wdrożyć program, aby ich przestrzegać.
Teraz znajomość tych reguł i przestrzeganie ich w C nie wymaga zrozumienia „sterty” i „stosu”. Ale jeśli rozumiesz, jak działają struktury danych, często łatwiej jest zrozumieć i przestrzegać zasad.
Pisząc książkę dla początkujących, naturalne jest, że autor wyjaśnia pojęcia w tej samej kolejności, w jakiej się ich nauczył. To niekoniecznie kolejność, która ma sens dla użytkownika. Niedawno byłem redaktorem ds. Technicznych książki dla początkujących C # 4 Scotta Dormana, a jedną z rzeczy, które mi się podobały, było to, że Scott wybrał dość rozsądną kolejność tematów, zamiast zaczynać od naprawdę zaawansowanych tematów w zarządzaniu pamięcią.
Innym powodem jest to, że niektóre strony w dokumentacji MSDN silnie podkreślają kwestie związane z pamięcią masową. Szczególnie starsza dokumentacja MSDN, która wciąż kręci się od pierwszych dni. Znaczna część tej dokumentacji zawiera subtelne błędy, które nigdy nie zostały usunięte, i musisz pamiętać, że została napisana w określonym czasie w historii i dla określonej grupy odbiorców.
Dlaczego stos zamiast sterty ma nawet znaczenie dla (początkujących) programistów .NET?
Moim zdaniem tak nie jest. O wiele ważniejsze jest zrozumienie takich rzeczy jak:
- Jaka jest różnica w semantyce kopiowania między typem odniesienia a typem wartości?
- Jak zachowuje się parametr „ref int x”?
- Dlaczego typy wartości powinny być niezmienne?
I tak dalej.
Przydzielasz rzeczy i to po prostu działa, prawda?
To jest idealne.
Są sytuacje, w których ma to znaczenie. Odśmiecanie jest niesamowite i stosunkowo niedrogie, ale nie jest bezpłatne. Kopiowanie małych struktur jest stosunkowo niedrogie, ale nie jest darmowe. Istnieją realistyczne scenariusze wydajności, w których należy zrównoważyć koszty presji zbierania i koszty nadmiernego kopiowania. W takich przypadkach bardzo pomocne jest dokładne zrozumienie wielkości, lokalizacji i rzeczywistego czasu życia całej odpowiedniej pamięci.
Podobnie istnieją realistyczne scenariusze interakcji, w których trzeba wiedzieć, co znajduje się na stosie, a co na stercie i co może przemieszczać się śmieciarz. Właśnie dlatego C # ma funkcje takie jak „naprawiono”, „stackalloc” i tak dalej.
Ale to są wszystkie zaawansowane scenariusze. Idealnie początkujący programista nie musi się martwić o nic z tych rzeczy.