Wybieranie między klasą i strukturą
Uwaga
Ta zawartość jest drukowana przez uprawnienie Pearson Education, Inc. z Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Wydanie to zostało opublikowane w 2008 roku, a książka została w pełni zmieniona w trzecim wydaniu. Niektóre informacje na tej stronie mogą być nieaktualne.
Jedną z podstawowych decyzji projektowych każdego projektanta platformy jest to, czy projektować typ jako klasę (typ odwołania) lub jako strukturę (typ wartości). Dobre zrozumienie różnic w zachowaniu typów odwołań i typów wartości ma kluczowe znaczenie w podejmowaniu tego wyboru.
Pierwszą różnicą między typami referencyjnymi a typami wartości, które należy wziąć pod uwagę, jest to, że typy referencyjne są przydzielane na stercie i odśmiecania pamięci, podczas gdy typy wartości są przydzielane na stosie lub wbudowane w typy zawierające typy i cofnięto przydział stosu lub gdy ich typ zawierający zostaje cofnięty. W związku z tym alokacje i przydziały typów wartości są ogólnie tańsze niż alokacje i przydziały typów referencyjnych.
Następnie tablice typów odwołań są przydzielane poza wierszem, co oznacza, że elementy tablicy są po prostu odwołaniami do wystąpień typu odwołania znajdującego się na stercie. Tablice typów wartości są przydzielane w tekście, co oznacza, że elementy tablicy są rzeczywistymi wystąpieniami typu wartości. W związku z tym alokacje i przydziały tablic typów wartości są znacznie tańsze niż alokacje i przydziały tablic typów odwołań. Ponadto w większości przypadków tablice typu wartości wykazują znacznie lepszą lokalność odwołania.
Następna różnica jest związana z użyciem pamięci. Typy wartości są wyświetlane podczas rzutowania do typu odwołania lub jednego z implementowanych interfejsów. Są one rozpiętowane po odrzuceniu z powrotem do typu wartości. Ze względu na to, że pola są obiektami przydzielonymi na stercie i są wyrzucane śmieci, zbyt wiele boksów i rozpałek może mieć negatywny wpływ na stertę, moduł odśmiecania pamięci i ostatecznie wydajność aplikacji. Z kolei nie ma takiego boksu, ponieważ typy odwołań są rzutowane. (Aby uzyskać więcej informacji, zobacz Boxing i Unboxing).
Następnie przypisania typów odwołań kopiują odwołanie, podczas gdy przypisania typu wartości kopiują całą wartość. W związku z tym przypisania dużych typów odwołań są tańsze niż przypisania dużych typów wartości.
Na koniec typy referencyjne są przekazywane przez odwołanie, podczas gdy typy wartości są przekazywane przez wartość. Zmiany w wystąpieniu typu odwołania mają wpływ na wszystkie odwołania wskazujące wystąpienie. Wystąpienia typu wartości są kopiowane po przekazaniu ich przez wartość. Gdy wystąpienie typu wartości zostanie zmienione, oczywiście nie ma wpływu na żadną z jego kopii. Ponieważ kopie nie są tworzone jawnie przez użytkownika, ale są niejawnie tworzone, gdy argumenty są przekazywane lub zwracane wartości, typy wartości, które można zmienić, mogą być mylące dla wielu użytkowników. W związku z tym typy wartości powinny być niezmienne.
Jako reguła kciuka większość typów w strukturze powinna być klasami. Istnieją jednak pewne sytuacje, w których cechy typu wartości sprawiają, że bardziej odpowiednie jest użycie struktur.
✔️ ROZWAŻ zdefiniowanie struktury zamiast klasy, jeśli wystąpienia typu są małe i często krótkotrwałe lub są często osadzone w innych obiektach.
❌ UNIKAJ definiowania struktury, chyba że typ ma wszystkie następujące cechy:
Logicznie reprezentuje jedną wartość, podobną do typów pierwotnych (
int
double
, itp.).Ma rozmiar wystąpienia poniżej 16 bajtów.
Jest niezmienny.
Nie będzie musiał być często boksowany.
We wszystkich innych przypadkach należy zdefiniować typy jako klasy.
© Części 2005, 2009 Microsoft Corporation. Wszelkie prawa zastrzeżone.
Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published oct 22, 2008 by Addison-Wesley Professional w ramach Microsoft Windows Development Series.