Struktury i typy wyliczeniowe w C#
1. Wprowadzenie
W języku C# zarówno struktury (struct), jak i typy wyliczeniowe (enum) służą do definiowania własnych typów danych, które pozwalają na lepsze modelowanie problemów w programowaniu. Są one szczególnie przydatne w przypadku prostych danych, które nie wymagają pełnej funkcjonalności klas.
Ważne jest zrozumienie, że:
- Struktury są typami wartościowymi (value types), co oznacza, że przechowują dane bezpośrednio, a nie odwołanie do nich.
- Typy wyliczeniowe są również typami wartościowymi, które reprezentują zestaw nazwanych stałych liczbowych.
2. Struktury (struct)
2.1 Definicja
Struktura w C# to typ wartościowy, który może zawierać:
- pola (fields)
- właściwości (properties)
- metody (methods)
- konstruktory
- zdarzenia (events)
- indeksatory (indexers)
- implementować interfejsy (interfaces)
Składnia definicji struktury:
2.2 Właściwości struktur
- Typ wartościowy – kopiowanie struktury tworzy nową instancję z tymi samymi danymi.
- Brak dziedziczenia – struktury nie mogą dziedziczyć po innych strukturach ani klasach (ale mogą implementować interfejsy).
- Domyślny konstruktor – każda struktura posiada domyślny konstruktor bez parametrów, który inicjalizuje wszystkie pola wartościami domyślnymi.
- Optymalizacja pamięci – struktury są przechowywane na stosie lub inline w tablicach i innych typach, co może zwiększać wydajność przy małych obiektach.
2.3 Przykład użycia
W tym przykładzie zmiana
p2nie wpływa nap1, ponieważ struktury są kopiowane jako wartości, a nie referencje.
3. Typy wyliczeniowe (enum)
3.1 Definicja
Typ wyliczeniowy (enum) to zestaw nazwanych stałych, które są powiązane z wartościami liczbowymi. Domyślnie jest to typ całkowity int.
Składnia definicji:
Można jawnie przypisać wartości liczbowe:
Możliwe jest też określenie typu podstawowego innego niż int:
3.2 Właściwości enum
- Typ wartościowy – przechowuje liczby całkowite.
- Czytelność kodu – nazwy stałych poprawiają zrozumiałość w kodzie zamiast używania „magicznych” liczb.
- Konwersja – można konwertować enum do i z typów liczbowych.
3.3 Przykład użycia
3.4 Kombinacje flag (Flags)
Enum można używać do reprezentowania zbiorów wartości dzięki atrybutowi [Flags].
4. Różnice między strukturami a klasami
| Cecha | Struktura (struct) | Klasa (class) |
|---|---|---|
| Typ | Wartościowy (value type) | Referencyjny (reference type) |
| Przechowywanie | Stos lub inline | Sterta (heap) |
| Dziedziczenie | Nie może dziedziczyć | Może dziedziczyć |
| Konstruktor bez parametrów | Tak, domyślny | Tak, domyślny |
| Przekazywanie | Kopia wartości | Referencja |