programowanieProgramista VB.NET, architekt

Opisz cechy i prawidłowe użycie struktur (Structure) w Visual Basic w porównaniu z klasami (Class). Jakie ograniczenia istnieją przy ich zastosowaniu i czym różnią się od klas pod względem zarządzania pamięcią i zachowania?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Visual Basic struktury definiowane są za pomocą słowa kluczowego Structure. Są one:

  • Typami wartości (value type): umieszczane w stosie lub wewnątrz innych obiektów;
  • Nie wspierają dziedziczenia od innych typów użytkownika (ale mogą implementować interfejsy);
  • Nie mogą mieć konstruktora bez parametrów, oprócz standardowego konstruktora poza ciałem struktury;
  • Nie mogą być deklarowane jako MustInherit (abstrakcyjne) ani zawierać finalizatorów;
  • Są dobrym wyborem do małych, niemutowalnych obiektów, oszczędzających pamięć w stercie.

Przykład

Public Structure Point Public X As Integer Public Y As Integer Public Sub New(x As Integer, y As Integer) Me.X = x Me.Y = y End Sub End Structure Dim p1 As New Point(1, 2) Dim p2 = p1 ' Wartość jest kopiowana, nie odniesienie! p2.X = 5 ' p1.X = 1, p2.X = 5

Ograniczenia

  • Struktury nie mogą dziedziczyć od siebie, tylko od System.ValueType.
  • Tylko automatyczny konstruktor bez parametrów.
  • Dozwolone są tylko interfejsy do implementacji.
  • Jeśli struktura zawiera członków referencyjnych, należy zachować ostrożność z powodu możliwych niuansów kopiowania i mutacji.

Pytanie z pułapką

P: Jak zachowuje się struktura przy przekazywaniu do funkcji ByVal i ByRef? Czym różni się to od przekazywania klasy?

O: Przy przekazywaniu struktury ByVal tworzona jest kopia całej struktury. Zmiany w funkcji nie dotyczą oryginału. Przy ByRef — zmieniana jest oryginalna zmienna. W odróżnieniu od klas, które przy każdej transakcji (nawet ByVal) przekazują odniesienie, struktury przy ByVal są w pełni kopiowane, co wpływa na wydajność i zachowanie.

Sub MutateByVal(p As Point) p.X = 100 End Sub Sub MutateByRef(ByRef p As Point) p.X = 100 End Sub Dim s As New Point(3, 4) MutateByVal(s) ' s.X wciąż 3 MutateByRef(s) ' s.X teraz 100

Historia

1. W dużym projekcie bibliotecznym struktury były używane do przesyłania dużych zestawów danych przez interfejsy ByVal. Doprowadziło to do spadku wydajności z powodu wielokrotnego kopiowania dużych struktur na stosie. Problem rozwiązano, zastępując struktury niemutowalnymi klasami.


Historia

2. W projekcie GIS pojawiło się zamieszanie przy kopiowaniu struktur zawierających pola referencyjne — zmieniając tablicę wewnątrz struktury, programista nie spodziewał się, że oryginał zmieni się wszędzie, gdzie skopiowano tablicę, mimo że to „typ wartości”.


Historia

**3. W oprogramowaniu księgowym mieszano struktury z klasami dla byty biznesowe: próba wdrożenia dziedziczenia dla struktury zakończyła się błędem kompilacji, trzeba było zreorganizować architekturę systemu, co okazało się czasochłonne z powodu pierwotnie błędnego wyboru między strukturami a klasami.