![]() |
AW: Wie *schnell* auf Properties anhand eines String-Bezeichners zugreifen?
Zitat:
Definiere für jede Klasse deiner Datenobjekte einen enumerated type, nennen wir ihn mal TPropEnum, der für jede der betroffenen Properties einen Identifier enthält. Gib der Klasse eine Methode, die als Parameter Werte dieser Enumerierung bekommt und den Wert der zugeordneten Property zurückgibt (eventuell als Variant wenn die Properties unterschiedliche Typen haben können). Die Implementierung ist ein simples case-Statement, und das ist schnell. Was Du dann noch brauchst ist ein Mapping der Feldnamen auf Werte des enumerated types. Die Quelle dafür kann ein simpler array [TPropEnum] of string sein. Dazu gehört dann ein TDictionary<string,TPropEnum>, das Du *einmal* aus dem Array initialisierst. Damit kannst Du dann anhand des Dictionaries einen Feldnamen schnell auf einen Wert der Enumeration mappen und mit dem dann den Wert aus dem Objekt holen. Das ist noch optimierbar, erfordert dazu aber eine Umarbeitung der Klassen. Du könntest die Daten nämlich direkt in einem Feld des Types array [TPropEnum] of variant speichern anstelle einzelner Felder pro Property, und für die Properties dann Getter und Setter implementieren, die auf den internen Array zugreifen. Siehe index keyword für Properties. Als Index kann auch ein enumerated type verwendet werden. Eine Alternative gäbe es da noch, aber dafür müßten die Properties published sein, damit RTTI (die klassische Variante) für sie erzeugt wird. Dann könntest Du nämlich ein TDictionary<string,PPropinfo> bauen, um die Feldnamen mit den Properties zu verbinden. Mit den Helferroutinen aus der system.TypInfo Unit kann man den Wert einer Property mittels des zugehörigen PPropInfo extrahieren. |
AW: Wie *schnell* auf Properties anhand eines String-Bezeichners zugreifen?
Am schnellsten wäre, wenn du ein Dictionary mit dem Feldnamen und dem Pointer auf den jeweiligen Getter erstellst. Dazu noch ein bisschen Casting und eine Prise Generics, dann sollte so etwas in der Art möglich sein:
Code:
type
TGenericGetter<T> = function: T of object; FFields: TDictionary<string, Pointer>; function TFieldAccess.Get<T>(const AObject: TObject; AFieldName: string; out AData: T): Boolean; var FieldAddress: Pointer; Getter: TGenericGetter<T>; GetterMethod: TMethod; begin Result := FFields.TryGet(AFieldName, FieldAddress); if Result then begin GetterMethod.Data := AObject; GetterMethod.Code := FieldAddress; AData := TGenericGetter<T>(GetterMethod); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz