Czym różni się struktura od klasy?
Każdy Ci powie, że struktura jest typem wartościowym, a klasa referencyjnym. I co z tego wynika? Że struktury są przekazywane przez parametry tak jak int, double, czy byte. Przekazywana jest ich kopia:
void Foo(int a)
{
a += 5;
}
void Main()
{
int i = 5;
Foo(i);
}
Po tym kodzie zmienna i cały czas będzie miała wartość 5. Do metody Foo została przekazana jakaś tymczasowa kopia tej zmiennej. Ale możemy też ją przekazać przez referencję:
void Foo(ref int a)
{
a += 5;
}
void Main()
{
int i = 5;
Foo(ref i);
}
Po tym kodzie, zmienna i będzie miała wartość 10, ponieważ została przekazana przez referencję. Czyli w pewnym sensie przez wskaźnik. Tutaj w metodzie Foo operujesz bezpośrednio na zmiennej i, a nie na jej kopii.
I teraz domyślnym zachowaniem dla klas (typów referencyjnych) jest przekazywanie ich do metod przez referencję. Domyślnym zachowaniem dla typów wartościowych jest przekazywanie ich do metod za pomocą kopii. A skoro struktura jest typem wartościowym, to zostanie przekazana jej kopia.
Kiedy używać struktur
Wtedy, gdy struktura reprezentuje coś w rodzaju typu liczbowego. Nie wiem, jak to wyjaśnić lepiej, więc przykład.
Liczba zespolona. Składa się z części rzeczywistej i urojonej. A więc ma jakby dwa składniki. Nie przedstawisz liczby zespolonej jako inta, więc musisz zrobić z tego strukturę:
struct Complex
{
public int Real { get; }
public int Imaginary { get; }
}
Różnica jest jeszcze taka, że struktury mają być immutable. Czyli nie możesz zmienić raz utworzonej struktury. Za każdym razem musisz ją tworzyć na nowo:
Complex c = new Complex(1, 2);
To jest jedyny możliwy sposób zmiany struktury.
Innym przykładem na zastosowanie struktury jest np. Punkt. To też jest kilka składowych, które tworzą pewną całość.
Także struktur używaj w prostych przypadkach, w których reprezentują one coś w rodzaju jednej "liczby" (nie umiem tego lepiej wyjaśnić :)) - liczba zespolona, punkt, data (dzień / miesiąc / rok) itd.
Wszędzie indziej używaj klas.