Delphi TRSBoxPrimitive<T> – generyczny wrapper prymitywów dla ARC, BoxPrimitives.pas, TStrings

Pytanie

co to jest w delphi : TRSBoxPrimitive&amp;lt;T&amp;gt;

Odpowiedź Sztucznej Inteligencji


Bezpośrednia odpowiedź na pytanie

  • TRSBoxPrimitive to generyczny „boxer” (opakowanie) typu wartościowego na obiekt, używany w Delphi głównie na mobilnych kompilatorach z ARC (iOS/Android sprzed 10.4), aby móc przechowywać prymitywy (np. Integer, Single) w kolekcjach oczekujących TObject, takich jak TStrings/TStringList.Items.Objects czy FMX TComboBox.Items. Pochodzi z jednostki pomocniczej BoxPrimitives.pas (autor: RiverSoftAVG). (blogs.riversoftavg.com)
  • Od RAD Studio 10.4 (maj 2020) Embarcadero usunęło ARC z mobilnych kompilatorów i zunifikowało zarządzanie pamięcią – w nowych projektach „boxer” zwykle nie jest już potrzebny. (docwiki.embarcadero.com)

Szczegółowa analiza problemu

  • Kontekst techniczny:
    • Historycznie TStrings/TStringList (także Items w TComboBox/TListBox) przechowują pary tekst + TObject. Gdy trzeba dołączyć do elementu liczbę (np. ID), na Windows często rzutowano Integer↔TObject. Na mobilnych kompilatorach z ARC i „NextGen RTL” takie rzutowanie było niedozwolone/niezalecane – stąd potrzeba „opakowania” prymitywu w obiekt. TRSBoxPrimitive rozwiązywał dokładnie ten problem. (stackoverflow.com)
  • Idea „boxera”:
    • Minimalna postać (upraszczając) wygląda tak:
      type
        TRSBoxPrimitive<T> = class(TObject)
        private
          FValue: T;
        public
          constructor Create(const AValue: T);
          property Value: T read FValue;
        end;
      • Tworzono aliasy typu TBoxInteger = TRSBoxPrimitive itd., aby transparenie używać AddObject i odczytywać Value. Przykładowe użycie (FMX/TComboBox):
        // dodanie
        ComboBox.Items.AddObject('Male', TBoxInteger.Create(1));
        // odczyt
        ShowMessage(IntToStr(TBoxInteger(ComboBox.Items.Objects[i]).Value));

        Mechanikę i wzorce użycia znajdziesz w odpowiedzi na SO, która cytuje i omawia BoxPrimitives.pas. (stackoverflow.com)

  • Warunkowa kompilacja i zgodność wersji:
    • W BoxPrimitives.pas i w kodzie aplikacji stosowano dyrektywę {$IFDEF AUTOREFCOUNT}, aby włączać „boxera” tylko dla kompilatorów z ARC. Od RAD Studio 10.4 flaga AUTOREFCOUNT została usunięta (ARC wyłączone na mobile), więc sekcje z „boxerem” mogą być pomijane, a proste rzutowanie na TObject znów działa jak na Windows. (docwiki.embarcadero.com)
    • Przykład bez rozgałęzień (wzorzec z SO): w sekcji {$ELSE} definiuje się aliasy, dzięki czemu to samo API działa na wszystkich platformach (na ARC – prawdziwy boxer; bez ARC – aliasy do TObject/typów prymitywnych). (stackoverflow.com)
  • Co to oznacza dziś (2026-01-03):
    • Jeśli kompilujesz w Delphi 10.4+ (Sydney i nowsze, w tym Delphi 12.x), najczęściej nie potrzebujesz TRSBoxPrimitive. Jeśli jednak utrzymujesz starszy kod mobilny (Rio i wcześniejsze) lub chcesz mieć jedno źródło zgodne wstecz, wzorzec z aliasami pozostaje użyteczny. (docwiki.embarcadero.com)

Aktualne informacje i trendy

  • Od 10.4 obowiązuje „Unified Memory Management” – brak ARC dla obiektów na wszystkich platformach; AUTOREFCOUNT i NEXTGEN zostały wycofane. To upraszcza kod i eliminuje potrzebę dodatkowych opakowań prymitywów w większości przypadków. (docwiki.embarcadero.com)
  • Obecna praktyka: zamiast wiązać dane z TStrings.Objects, częściej używa się kolekcji generycznych (TList, TObjectList, TDictionary<K,V>) lub własnych modeli danych powiązanych z kontrolkami (MVVM/MVP).

Wspierające wyjaśnienia i detale

  • Dlaczego w ogóle „boxer”?
    • TStrings.Objects przechowuje TObject. Przechowywanie liczb wymaga obiektu. TRSBoxPrimitive dostarcza lekki, generyczny wrapper bez wiązania z konkretnym typem.
  • Bezpieczeństwo typów:
    • Przy odczycie zawsze wykonuj rzutowanie do właściwego typu „boxera” (np. TBoxInteger). W kodzie wieloplatformowym warto enkapsulować to w pomocniczych funkcjach, aby uniknąć rozrzuconych rzutowań.
  • Alternatywy:
    • W nowych projektach rozważ:
      • TList / TArray i osobne mapowanie do wizualnych Items.
      • Słowniki (TDictionary<string,Integer>) i wypełnianie kontrolek na podstawie kluczy.

Aspekty etyczne i prawne

  • BoxPrimitives.pas był publicznie udostępnionym przykładem (blog RiverSoftAVG). Zweryfikuj licencję pliku przed dystrybucją produkcyjną, zwłaszcza jeśli modyfikujesz kod. (blogs.riversoftavg.com)
  • Pamiętaj o odpowiedzialnym zarządzaniu pamięcią: TStrings nie „posiada” obiektów domyślnie – jeśli używasz „boxera” w wersjach bez ARC, dopilnuj ich zwalniania (np. ręcznie lub za pomocą kolekcji, które „posiadają” elementy).

Praktyczne wskazówki

  • Jeśli trafiasz w kodzie na TRSBoxPrimitive:
    • Sprawdź wersję Delphi. Dla 10.4+ rozważ usunięcie zależności lub pozostaw aliasy, by zachować kompatybilność źródeł.
    • Użyj wzorca kompilacji warunkowej:
      {$ifdef AUTOREFCOUNT}
      uses BoxPrimitives;
      {$endif}

      i odpowiednich aliasów w BoxPrimitives.pas, aby jednocześnie wspierać stare i nowe kompilatory. (stackoverflow.com)

  • Nowe projekty:
    • Preferuj kolekcje generyczne i warstwę modelu danych zamiast „wciskania” wartości w Objects[].

Ewentualne zastrzeżenia lub uwagi dodatkowe

  • Nazwa z prefiksem „RS” może kojarzyć się z bibliotekami RiverSoftAVG od grafiki/SVG i innych – to nie jest wbudowany element RTL/VCL/FM. Jeśli masz wątpliwości, w IDE użyj „Find Declaration”/Ctrl+Click, aby potwierdzić, że definicja pochodzi z BoxPrimitives.pas.
  • Spotyka się też inne generyczne „boxery” (np. TBox w społeczności). To podobny pomysł, lecz nie jest to samo co TRSBoxPrimitive.

Sugestie dalszych badań

  • Artykuł źródłowy: „Using Primitive Types with TStrings in iOS” (RiverSoftAVG) – tło i motywacja BoxPrimitives. (blogs.riversoftavg.com)
  • „Using TStringList.AddObject in Delphi Android FMX” – dyskusja i gotowy wzorzec aliasów dla 10.4+. (stackoverflow.com)
  • DocWiki: „What’s New” (10.4) i tabela warunków kompilacji (AUTOREFCOUNT usunięte) – podstawa dla decyzji migracyjnych. (docwiki.embarcadero.com)

Krótkie podsumowanie

  • TRSBoxPrimitive to generyczny wrapper prymitywów na TObject z BoxPrimitives.pas, stworzony dla kompilatorów ARC (mobile) w celu używania prymitywów w TStrings/Items.Objects. W erze 10.4+ (Unified Memory Management) jego użycie w nowych projektach jest zwykle zbędne; w kodzie wielowersyjnym można zachować wzorzec z aliasami, by utrzymać jedną bazę źródeł. (stackoverflow.com)

Oceń odpowiedź:
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.

Zadaj dodatkowe pytanie Sztucznej Inteligencji

Czekaj (2min)...