programowanieVB.NET deweloper

Jak zaimplementować właściwości (properties) z obsługą wartości obliczanych (Calculated Properties) w Visual Basic i jak bezpiecznie współpracować z prywatnymi polami wewnątrz właściwości?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania
Właściwości w Visual Basic pozwalają na enkapsulację logiki pobierania i ustawiania wartości. Wprowadzenie właściwości sprawia, że kod staje się bardziej czytelny i bezpieczny, eliminując potrzebę bezpośredniego dostępu do pól klasy i ułatwiając wdrażanie logiki walidacji lub obliczeń bezpośrednio w obiektach.

Problem
Nowicjusze często udostępniają pole publicznie lub używają właściwości automatycznych bez gettera/settera zawierających logikę, co prowadzi do naruszenia enkapsulacji lub niemożności realizacji wartości obliczanych. Innym problemem jest rekurencyjne wywołanie właściwości wewnątrz samej siebie, co prowadzi do StackOverflow.

Rozwiązanie
W Visual Basic ogłasza się prywatne pole, a właściwość zawiera bloki Get i Set z potrzebną logiką. Właściwości obliczane używają tylko Get, zwracając obliczoną wartość na podstawie prywatnych pól. Wewnątrz bloku set zawsze należy odwoływać się do prywatnego pola, aby uniknąć nieskończonej rekurencji.

Przykład kodu:

Private _price As Decimal Private _quantity As Integer Public Property Total As Decimal Get Return _price * _quantity ' właściwość obliczana End Get End Property Public Property Price As Decimal Get Return _price End Get Set(value As Decimal) If value < 0 Then Throw New ArgumentException("Price must be positive") _price = value End Set End Property

Kluczowe cechy:

  • Enkapsulacja dostępu do danych wewnętrznych.
  • Możliwość dodania logiki sprawdzającej lub dodatkowego przetwarzania podczas pobierania/przypisywania.
  • Różnica między właściwością tylko do odczytu a do zapisu.

Pytania z podstępem.

Czy można w obrębie Set Price odwoływać się do właściwości Name, jeśli również jest zaimplementowana przez prywatne pole?

Tak, jeśli w bloku set właściwości Price odwołasz się do innej właściwości (np. Name), jest to dozwolone, ponieważ odwołania do różnych prywatnych pól nie wywołują rekurencji. Należy unikać odwoływania się do samego siebie: wywołanie Price wewnątrz Set Price spowoduje rekurencję.

Przykład kodu:

Public Property Name As String Get Return _name End Get Set(value As String) _name = value End Set End Property Public Property Price As Decimal Get Return _price End Get Set(value As Decimal) If Name Is Nothing Then _name = "default" _price = value End Set End Property

Co się stanie, jeśli w bloku Get właściwości wywołam tę właściwość ponownie?

To doprowadzi do nieskończonej rekurencji i StackOverflow. W bloku get zawsze używaj prywatnego pola, w przeciwnym razie właściwość będzie wywoływać samą siebie.

Public Property Amount As Decimal Get Return Amount ' doprowadzi do nieskończonej rekurencji End Get Set(value As Decimal) _amount = value End Set End Property

Czy można zadeklarować właściwość tylko do zapisu (WriteOnly) i jakie to niesie ryzyko?

Istnieją właściwości WriteOnly, ale ich użycie nie jest zalecane, ponieważ obiekt traci możliwość zwrócenia wartości, co pogarsza czytelność i przewidywalność. Jeśli jest potrzebna tylko do zapisu — lepiej przemyśleć architekturę.

Private _secret As String Public WriteOnly Property Secret As String Set(value As String) _secret = value ' Można zapisać, ale nie można uzyskać. End Set End Property

Typowe błędy i antywzorce

  • Rekursywne wywołanie właściwości wewnątrz siebie zamiast odwoływania się do prywatnego pola.
  • Publiczne pola zamiast właściwości, co narusza enkapsulację.
  • Tworzenie właściwości WriteOnly bez wyraźnej potrzeby.
  • Brak sprawdzania danych wejściowych w bloku set.

Przykład z życia

Negatywny przypadek

Programista postanowił uczynić pole Price publicznym i bezpośrednio z nim pracował. W rezultacie Price czasami stawał się ujemny przez błąd.

Zalety:

  • Szybka realizacja, minimum kodu.

Wady:

  • Brak enkapsulacji.
  • Logika walidacji niemożliwa.
  • Łatwo wprowadzić niedopuszczalną wartość.

Pozytywny przypadek

Kolega zastąpił Price właściwością z prywatnym polem i walidacją w bloku set, co zapobiegło nieprawidłowym wartościom.

Zalety:

  • Bezpieczeństwo danych.
  • Elastyczność w rozwijaniu kodu.

Wady:

  • Nieco zwiększył objętość kodu.