Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Generic ObjectList und Suchen - Wie am besten ? (https://www.delphipraxis.net/181321-generic-objectlist-und-suchen-wie-am-besten.html)

Stevie 6. Aug 2014 13:48

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Zitat:

Zitat von OlafSt (Beitrag 1267732)
WTF ist ein constraint ? Irgendwie hab ich was verpaßt, glaub ich ;)

Gucksu hier

OlafSt 6. Aug 2014 13:58

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Kapiert. Nun bekomme ich eine Fehlermeldung:

E2010 Inkompatible Typen: 'System.SysUtils.TPredicate<Unit1.TDriverList<T>.T >' und 'Procedure'

Code wie folgt:
Delphi-Quellcode:
   TDriverList<T: TDriverBase> = class(TObjectList<T>)
   private
   protected
   public
      function Find(const Predicate: TPredicate<T>): T;
      function FindByIMEI(AIMEI: string): T;
      function FindByID(AID: string): T;
   end;
[...]
{ TDriverList<T> }

function TDriverList<T>.Find(const Predicate: TPredicate<T>): T;
begin
     for Result in self do
          if Predicate(Result) then
             exit;
     Result:=nil;
end;

function TDriverList<T>.FindByID(AID: string): T;
begin
     Result:=Find(
        function(Obj: TDriverBase): boolean
        begin
             Result:=(Obj.DriverID = AID);
        end); //<- Hier bleibt der Compiler stehen
end;
Ehrlich gesagt sehe ich den Fehler nicht. Find will als Param ein TPredicate und meine anonyme Methode hat doch die passenden Params?

Stevie 6. Aug 2014 14:27

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Die Fehlermeldung gibt dir hier leider nicht den letzlich zielführenden Hinweis, dass eigentlich die Signaturen nicht passen.

Find will TPredicate<T> und du gibst nur eine für TPredicate<TDriverBase> passende Funktion hinein.
Da du bei der Definition ja den Constraint TDriverBase auf T gesetzt hast, kannst kannst du einfach das hier schreiben:

Delphi-Quellcode:
function TDriverList<T>.FindByID(AID: string): T;
begin
     Result:=Find(
        function(Obj: T): boolean
        begin
             Result:=(Obj.DriverID = AID); // durch den Constraint weiß der Compiler, dass Obj von TDriverBase ist und kann auf seine Member zugreifen.
        end);
end;

Union 6. Aug 2014 14:28

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Deine anonyme Funktion muß so aussehen:
Delphi-Quellcode:
function(Obj: T): boolean
        begin
             Result:=(Obj.DriverID = AID);
        end);
[Edit]Kein rotes Fenster?[/EDIT]

OlafSt 6. Aug 2014 14:31

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Dann war meine Vermutung, die ich insgeheim schon hatte, ja korrekt. In C# ist dieses "Mitdenken" des Compilers ja fast schon normal :D, bei Delphi weiß man nie so genau, wie weit Emba da Intelligenz eingebaut hat ;)

Stevie 6. Aug 2014 14:41

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Zitat:

Zitat von OlafSt (Beitrag 1267749)
In C# ist dieses "Mitdenken" des Compilers ja fast schon normal :D, bei Delphi weiß man nie so genau, wie weit Emba da Intelligenz eingebaut hat ;)

So kann man es auch ausdrücken. Aber die Sache ist gerade bei Generics eher die, dass C# Type Variance kann und Delphi nicht. Und dass man dort eher Lambdas benutzt, die sowieso Type Inference können.

Sir Rufo 6. Aug 2014 15:42

AW: Generic ObjectList und Suchen - Wie am besten ?
 
Und dann gibt es noch
Delphi-Quellcode:
TDriverList<T:TDriverBase> = ...
  ...
  function FindById( const AID : string ) : T; overload;
  function FindById<TFind : T>( const AID : string ) : TFind; overload;
end;

function TDriverList<T>.FindById<TFind>( const AID : string ) : TFind;
begin
  Result := Find(
    function( Arg : T ) : Boolean
    begin
      Result := ( Arg is TFind ) and ( Arg.ID = AID );
    end ) as TFind;
end;
und du hast deine Spezialklassen auch typsicher abgebildet ;)
Delphi-Quellcode:
var
  MyDriverList : TDriverList<TDriverBase>;
  MySpecialDriver : TSpecialDriver;

MySpecialDriver := MyDriverList.FindById<TSpecialDriver>( '42' );


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:20 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz