Sdílet prostřednictvím


Volba mezi třídou a strukturou

Poznámka:

Tento obsah je znovu vytištěn oprávněním Pearson Education, Inc. z Framework Design Guidelines: Conventions, Idioms a Patterns for Reusable .NET Libraries, 2. vydání. Tato edice byla publikována v roce 2008 a kniha byla od té doby plně upravena ve třetím vydání. Některé informace na této stránce můžou být zastaralé.

Jedním ze základních rozhodnutí o návrhu každého návrháře architektury je to, jestli navrhnout typ jako třídu (odkazový typ) nebo jako strukturu (typ hodnoty). Při této volbě je důležité porozumět rozdílům v chování referenčních typů a hodnotových typů.

První rozdíl mezi referenčními typy a typy hodnot, který budeme zvažovat, je ten, že referenční typy jsou alokovány na haldě a automaticky uvolněny (sbírané), zatímco typy hodnot jsou alokovány buď na zásobníku, nebo jsou vloženy do obsahujících typů, a jsou uvolněny, když se zásobník vyprázdní nebo když se jejich obsahující typ uvolní z paměti. Přidělení a uvolnění typů hodnot jsou proto obecně levnější než přidělení a uvolnění referenčních typů.

Dále jsou pole referenčních typů přidělena mimo řádek, což znamená, že prvky pole jsou pouze odkazy na instance typu odkazu, které se nacházejí v haldě. Pole typů hodnot jsou alokována přímo, což znamená, že prvky pole jsou skutečnými instancemi typu hodnoty. Přidělení a uvolnění hodnotových typů jsou proto mnohem levnější než přidělení a uvolnění referenčních typů. Kromě toho pole hodnotových typů ve většině případů vykazují mnohem lepší lokalitu odkazů.

Další rozdíl souvisí s využitím paměti. Typy hodnot se při přetypování do referenčního typu nebo jednoho z rozhraní, která implementují, zobrazí v rámečku. Při přetypování zpět na typ hodnoty se rozbalí. Protože boxy jsou objekty, které jsou přiděleny na haldě a jsou spravovány pomocí garbage collectoru, může mít příliš mnoho proměně do boxů a rozbalování negativní dopad na haldu, správce paměti a nakonec na výkon aplikace. Naproti tomu k žádnému takovému boxování nedojde, protože se přetypují odkazové typy. (Další informace naleznete v tématu Boxing and Unboxing).

Dále přiřazení typu odkazu zkopírují odkaz, zatímco přiřazení typu hodnoty zkopírují celou hodnotu. Přiřazení velkých referenčních typů jsou proto levnější než přiřazení velkých hodnotových typů.

Nakonec se odkazové typy předávají odkazem, zatímco typy hodnot se předávají hodnotou. Změny instance typu odkazu ovlivňují všechny odkazy odkazující na instanci. Instance typu hodnoty se zkopírují, když jsou předávány podle hodnoty. Když je instance typu hodnoty změněna, samozřejmě nemá vliv na žádné jeho kopie. Vzhledem k tomu, že kopie nejsou explicitně vytvořeny uživatelem, ale jsou implicitně vytvořeny při předávání argumentů nebo vracení návratových hodnot, mohou být měnitelné typy hodnot matoucí pro mnoho uživatelů. Proto by měly být typy hodnot neměnné.

Obecně platí, že většina typů v rámci by měla být třídy. Existují však některé situace, kdy vlastnosti typu hodnoty umožňují vhodnější použít struktury.

✔️ ZVAŽTE definování struktury místo třídy, pokud jsou instance typu malé a běžně krátkodobé nebo jsou běžně vloženy do jiných objektů.

❌ Vyhněte se definování struktury, pokud typ nemá všechny následující vlastnosti:

  • Logicky představuje jednu hodnotu, podobnou primitivním typům (int, doubleatd.).

  • Má velikost instance pod 16 bajtů.

  • Je neměnný.

  • Nebude ho nutné často balit do krabice.

Ve všech ostatních případech byste měli definovat typy jako třídy.

Části z © 2005, 2009 Microsoft Corporation. Všechna práva vyhrazena.

Přetištěno se svolením Pearson Education, Inc. z Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition od Krzysztofa Cwaliny a Brada Abramse, vydáno 22. října 2008 nakladatelstvím Addison-Wesley Professional jako součást série Microsoft Windows Development.

Viz také