![]() |
Delphi-Version: XE4
Generic ObjectList und Suchen - Wie am besten ?
Hallo Freunde,
heute mal was für Generic-Anfänger, wie ich es bin. Bisher hab ich die Dinger immer nur benutzt - das soll sich nun ändern. Ich habe immer wieder das Problem, das ich Objekte en masse in ObjectLists speichern und immer wieder das eine oder andere Objekt in dieser Liste suchen muß. Generics waren eine - wenn auch sehr codeaufblähende - prima Lösung. Nur das Gesuche ist noch immer "doof". Ich habe nun vor, mich dem Problem schrittweise zu nähern. Meine erste Idee:
Delphi-Quellcode:
Das funktioniert offenbar, weil es ohne Error compiliert :D Okay.
type
TMyObjectList<T> = class(TObjectList<T>);
Delphi-Quellcode:
Wie man sieht, ist mein Ansatz eine direkte Fahrt gegen die Wand. Zwei Fragen:
type
TMyObjectList<T> = class(TObjectList<T>); public function Search(ASearchCrit: integer): T; end; [...] function TMyObjectList<T>.Search(ASearchCrit: integer): T; begin for Result in Self do begin if Result. //<--- Äh... Das funktioniert nicht. Gar nicht end; end; 1. Wie löst man sowas ? 2. Da in TMyObjectList irgendwas gestopft werden kann - bin ich gezwungen, alle möglichen Typen zuerst abzutesten oder gibt es da auch eine clever Lösung ?
Delphi-Quellcode:
Thanks für die Schubser,
Result:=true;
if T is TDriver then exit; if T is TSpecialDriver then exit; if T is TExtraSpecialDriver then exit; Result:=false; Olaf |
AW: Generic ObjectList und Suchen - Wie am besten ?
Haben die Typen eine gemeinsamen Vorfahren? Soll einer davon ausgeschlossen werden? Wenn Ja, kannst du die Anweisungen zusammenfassen:
Delphi-Quellcode:
Wenn es für alle Nachfahren einer Klasse gelten soll prüfe gegen diese.
if T in [ TDriver, TSpecialDriver, TExtraSpecialDriver, ...] then Result := True else Result := False;
|
AW: Generic ObjectList und Suchen - Wie am besten ?
Ah, eine gute Idee !
Die Klassen haben einen gemeinsamen Vorfahren und es reicht, gegen den zu testen:
Delphi-Quellcode:
Damit sind alle Nachfahren erfaßt und zulässig, alle anderen Klassen wie z.B. TComponent oder TWorkTime (völlig andere Unit) eliminiert.
Result:=(T is TDriverBase);
Bleibt Problem 1. |
AW: Generic ObjectList und Suchen - Wie am besten ?
Ist ASearchCrit: Integer für alle zu unterstützenden Klassen in gleicher Weise die Suchbedingung?
Falls ja, könnte man entweder alle Klassen von einer ableiten die eine ID Property hat, und in der Schleife dann diese ID mit ASearchCrit vergleichen. Alternativ könnte man ein Interface benutzen, das alle Klassen unterstützen und das diese ID Property definiert, auch dann kann ASearchCrit mit der ID verglichen werden. Schliesslich gibt es noch die Möglichkeit Equals zu überschreiben. Doch das hat Risiken und Nebenwirkungen. |
AW: Generic ObjectList und Suchen - Wie am besten ?
Warum erzeugst du dann nicht eine typisierte generische Objektliste?
Delphi-Quellcode:
Problem 1 versteht ich nicht. Was willst Du machen?
TMyObjectList<T> = class(System.Generics.Collections.TObjectList<TDriverBase>)
public function Search(ASearchCrit: integer): T; end; |
AW: Generic ObjectList und Suchen - Wie am besten ?
Soweit ich verstanden habe, wird die List sehr groß. Wenn sowas passiert und man will darin suchen ... normalerweise sortiert man das Ding. Ansonsten kannst du nur eine
![]() Pseudo Lineare Suche:
Delphi-Quellcode:
Wird das Ding aber immer schön sortiert kannst du eine
for AnfangListe to EndeListe do
begin if Element=Gesucht then begin Result = ElementIndex // Oder was auch immer Break; end; end; ![]() Gruß Puke |
AW: Generic ObjectList und Suchen - Wie am besten ?
Delphi-Quellcode:
Einsatz:
type
TMyObjectList<T> = class(TObjectList<T>); public function Search(const predicate: TPredicate<T>): T; end;
Delphi-Quellcode:
Vorteil: Du schränkst deine generische Listenklasse nicht auf bestimmte Suchkriterien ein, die nur für bestimmte Arten von T gelten.
myDriver := driverList.Search(
function(d: TDriver): Boolean begin Result := d.Id = 1234 end); Wenn dir das Schreiben der anonymen Methode zu unhandlich ist, kannst du das auch noch auslagern:
Delphi-Quellcode:
Einsatz:
function DriverById(i: Integer): TPredicate<TDriver>;
begin Result := function(d: TDriver): Boolean begin Result := d.Id = i; end; end;
Delphi-Quellcode:
Eventuell kannst du dir auch Spring4D anschauen, die Listen dort unterstützen alle Arten von Suchen, Filtern, etcmyDriver := driverList.Search(DriverById(1234)); |
AW: Generic ObjectList und Suchen - Wie am besten ?
Er will ja aber nur Nachfahren einer bestimmte Klasse aufnehmen, deshalb erschien mir die Einschränkung sinnvoll.
|
AW: Generic ObjectList und Suchen - Wie am besten ?
Zitat:
|
AW: Generic ObjectList und Suchen - Wie am besten ?
Generics wurden in D2009 eingeführt
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:05 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-2025 by Thomas Breitkreuz