programowanieProgramista VB/VB.NET

Jak zaimplementować typy danych zdefiniowane przez użytkownika (User-Defined Types, UDT) w Visual Basic i w jakich przypadkach warto ich używać zamiast klas?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Visual Basic, typy danych zdefiniowane przez użytkownika (Type w VB6 lub Structure w VB.NET) pozwalają na definiowanie własnych złożonych typów, które zawierają kilka zmiennych różnych typów. Jest to wygodne do pakowania powiązanych danych.

UDT (VB6):

Type Person Name As String Age As Integer Height As Single End Type Dim employee As Person employee.Name = "Aleksey" employee.Age = 32 employee.Height = 1.85

Structures (VB.NET):

Structure Person Public Name As String Public Age As Integer Public Height As Single End Structure Dim employee As Person employee.Name = "Aleksey"

Kiedy używać:

  • Do lekkich kontenerów danych bez logiki
  • Gdy wydajność ma znaczenie (struktury są tworzone na stosie)
  • Jeśli nie potrzebna jest dziedziczona funkcjonalność — struktury nie obsługują dziedziczenia

W przeciwieństwie: Klasy są używane, gdy potrzebna jest enkapsulacja logiki, dziedziczenie, polimorfizm lub implementacja interfejsów.

Pytanie podchwytliwe

Dlaczego strukturom w VB.NET nie można przypisywać wartości Nothing?

Odpowiedź: Tylko zmiennym klasowym (obiektom) można przypisać Nothing, ponieważ przechowują one odniesienia. Struktury to typy wartości, które zawsze zawierają zestaw wartości; próba przypisania Nothing spowoduje błąd kompilacji.

Dim s As Person = Nothing 'Błąd! Struktury nie mogą być Nothing (z wyjątkiem Nullable(Of T))

Przykłady rzeczywistych błędów z powodu niewiedzy na temat subtelności tematu


Historia

W starym projekcie postanowiono zastąpić tablicę prymitywów strukturą z kilkoma polami, ale nowy kod niespodziewanie stał się wolniejszy. Okazało się: struktura była bardzo duża i często kopiowana do funkcji. Gdyby użyto klasy, kopiowane byłyby tylko odniesienia, a nie cała struktura.


Historia

Po przeniesieniu VB6-UDT do VB.NET jeden z deweloperów nie zaimplementował interfejsu ISerializable dla struktury w wywołaniu zdalnym. W rezultacie usuwany obiekt nie mógł być serializowany, co spowodowało awarie podczas międzyprocesowej komunikacji.


Historia

W module do pracy z geometrią struktura przechowywała odniesienia do tablic (mutable). Wiele instancji tej struktury prowadziło do nieoczekiwanych efektów, ponieważ w obrębie struktury odniesienia wskazywały na te same tablice danych — mutacje odbijały się na wszystkich kopiach!