AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Generische Ableitung TList<>

Ein Thema von Christoph Schneider · begonnen am 7. Okt 2008 · letzter Beitrag vom 19. Nov 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#1

Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:07
Toll die Spracherweiterung für generische Typen in D2009!
Nur, bei meiner ersten Anwendung einer TList<> Ableitung
habe ich leider erste Schwierigkeiten.
Denn ich möchte eine neue TList<> Ableitung erstellen,
welche auf einer eignen Elementen-Klasse basiert, die
nur ein ID-Property enthält, um später in der neuen List-Klasse
nach dieser ID zu suchen:

Delphi-Quellcode:
  TMyBase = class
  strict private
    fID: string;
  public
    constructor Create(ID: string);
    property ID: string read fID;
  end;

constructor TMyBase.Create(ID: string);
begin
  fID := ID;
end;
In der neuen Liste möchte ich abgeleitete Klassen von TMyBase
ablegen und mit einer neuen Methode FindByID wieder finden.

Delphi-Quellcode:
  TMyList<T> = class(TList<TMyBase>)
  public
    function FindByID(ID: string): TMyBase;
  end;

function TMyList<T>.FindByID(ID: string): TMyBase;
var
  c: integer;
begin
  result := nil;
  for c := 0 to Count - 1 do
    if (Items[c] as TMyBase).ID = ID then
      result := Items[c];
end;
Dies läuft so weit, nur scheint mir die nötige Typenkonvertierung
Items[c] as TMyBase fraglich.

Wenn ich jetzt eine Ableitung von TMyBase mache, sind in der
Anwendung weitere Konvertierungen nötig:
Delphi-Quellcode:
  TMyName = class(TMyBase)
  strict private
    fName: string;
  public
    constructor Create(ID, aName: string);
    property Name: string read fName;
  end;

constructor TMyName.Create(ID, aName: string);
begin
  inherited Create(ID);
  fName := aName;
end;
Die Anwendung:
Delphi-Quellcode:
UseMyList := TMyList<TMyName>.Create;
UseMyList.Add(TMyName.Create('ID-1', 'Meier'));
UseMyList.Add(TMyName.Create('ID-2', 'Müller'));
UseMyList.Add(TMyName.Create('ID-3', 'Tester'));

MyString := (UseMyList.FindByID('ID-3') as TMyName).Name;
Auch hier sollte meines erachtens die Typenonvertierung
(UseMyList.FindByID('ID-3') as TMyName)
nicht mehr nötig sein, damit das generische Konzept richtig umgesetzt wird.

Meine Vermutung ist, dass ich die FindByID Methode falsch deklariert habe,
und dass der Rückgabe-Typ hier <T> sein müsste. Leider bekomme ich mit folgender
Deklaration in D2009 neue Probleme, weil TMyBase nicht von T abgeleitet ist
(und ich auch keinen Weg fand, dies zu tun).
Delphi-Quellcode:
  TMyList<T> = class(TList<TMyBase>)
  public
    function FindByID(ID: string): T;
  end;
Bei einer echten Anwendung mit Duzenden von Ableitungen wird diese kleine
Unschönheit schnell zur grösseren Fehlerquelle. Deshalb möchte ich meinen
ersten Ansatz hinterfragen lassen.

Beiliegend die kurze Konsolen-Applikation zum Experimentieren, damit meine
Abhandlung nicht reine Theorie bleibt.

Danke für eure Lösungen.

Gruss Christoph

BTW: Refactoring von Klassennamen welche als Generische Typen verwendet werden
(hier TMyBase) scheint in D2009 (noch) nicht zu funktionieren. Gibt es einen
Workaround?
Angehängte Dateien
Dateityp: dpr project1_858.dpr (1,3 KB, 2x aufgerufen)
Christoph Schneider
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:11
Unterstützt Delphi keine generic constraints? Das wäre tödlich.. TMyList<T: TMyBase> = class(TList<T>)
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:27
Doch, genau das ist es! Damit lässt sicher das Problem lösen.

Jetzt habe ich nur noch ein weiteres Problem mit der Typenzuweisung
result := nil:

Delphi-Quellcode:
  TMyList<T: TMyBase> = class(TList<T>)
  public
    function FindByID(ID: string): T;
  end;

function TMyList<T>.FindByID(ID: string): T;
var
  c: integer;
begin
// result := nil; -> DCC Error: E2010 Incompatible types: T and pointer
  for c := 0 to Count - 1 do
    if Items[c].ID = ID then
      result := Items[c];
end;
Ich bin sicher, auch hierfür muss es eine Lösung geben!

Erstmal Besten Dank an Dax!
Angehängte Dateien
Dateityp: dpr project1_181.dpr (1,5 KB, 2x aufgerufen)
Christoph Schneider
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#4

Re: Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:29
Probier mal, ob es auch "T: class, TMyBase" oder etwas ähnliches annimmt - ansonsten dringend in die Sprachbeschreibung schauen Mit den Delphi-Generics kenne ich mich nun leider garnicht aus, dass constraints so notiert werden wie oben hab' ich auch nur aus einem Blog aufgeschnappt.
  Mit Zitat antworten Zitat
Benutzerbild von sniper_w
sniper_w

Registriert seit: 12. Dez 2004
Ort: Wien, Österriech
893 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:34
OT:
Nach dem ersten 30 Sekunden langen Blick scheint mir die Delphi Implementation von Generics unnötig kompliziert.
So der erste Eindruck.

OnToppic:
Probiere es mit :Result := TObject(nil);
Katura Haris
Es (ein gutes Wort) ist wie ein guter Baum, dessen Wurzel fest ist und dessen Zweige in den Himmel reichen.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#6

Re: Generische Ableitung TList<>

  Alt 7. Okt 2008, 18:37
Zitat von sniper_w:
OT:
Nach dem ersten 30 Sekunden langen Blick scheint mir die Delphi Implementation von Generics unnötig kompliziert.
So der erste Eindruck.
Von der Deklaration der Typparameter her sicherlich. Vor allem die Tatsache, dass Delphi scheinbar nicht in der Lage ist, aus "T: TMyBase" abzuleiten, dass T eine Klasse sein muss, tut weh...
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Generische Ableitung TList<>

  Alt 8. Okt 2008, 08:43
Leider erlaubt dies der Compiler nicht:

result := TObject(nil);
-> E2010: Incompatible Types T and TObject

Die Situation verändert sich auch nicht, wenn ich die
veraltete Deklaration der Basis-Klasse anwende:
TMyBase = class(TObject)

Natürlich läuft auch der naheliegende Typcast nicht
result := T(nil);
-> E2089: Invalid Typcast

Auch der Versuch mit der neuen Exit-Clause, die einen
Rückgabe-Parameter erlaubt geht nicht:
exit(nil);
-> E2010: Incompatible Types T and Pointer

Ich bin ratlos, kann mir aber nicht vorstellen, dass
dieses Triviale Konstrukt nicht lösbar sein sollte.
Christoph Schneider
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: Generische Ableitung TList<>

  Alt 8. Okt 2008, 09:11
Zitat von Christoph Schneider:
Ich bin ratlos, kann mir aber nicht vorstellen, dass
dieses Triviale Konstrukt nicht lösbar sein sollte.
"result:= Default( T );" sollten helfen.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Generische Ableitung TList<>

  Alt 8. Okt 2008, 09:43
Super, damit lässt sich auch das letzte Problem elegant lösen!

Gerne bilde ich die korrigierte Klasse TMyList nochmals vollständig ab.
Im Anhang lege gleich noch das ganze Konsolen-Projekt bei.

Delphi-Quellcode:
type
  TMyList<T: TMyBase> = class(TList<T>)
  public
    function FindByID(ID: string): T;
  end;

function TMyList<T>.FindByID(ID: string): T;
var
  c: integer;
begin
  result := Default(T);
  for c := 0 to Count - 1 do
    if Items[c].ID = ID then
      result := Items[c];
end;
Danke an alle für die Tatkräftige Unterstützung!

Das Help von D2009 ist im Vergleich zu D2005-D2007
spürbar besser. Leider enthalten die Kapitel
Overview of Generics und folgende aber keine
Hinweise zu dieser neuen Funktion Default. Auch sonst
finde ich keinen passenden Hinweis. Im Kapitel
Generic-Contraints sind alle Beispiele mit Interface
Klassen geführt, weswegen ich nicht gleich auf die
TMyList<T: TMyBase> kam.

Kennt Ihr eine gute Einführung in Generics von Delphi
auf dem Netz?
Angehängte Dateien
Dateityp: dpr project1_734.dpr (1,5 KB, 10x aufgerufen)
Christoph Schneider
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#10

Re: Generische Ableitung TList<>

  Alt 8. Okt 2008, 12:08
Zitat von Daniel:
Zitat von Christoph Schneider:
Ich bin ratlos, kann mir aber nicht vorstellen, dass
dieses Triviale Konstrukt nicht lösbar sein sollte.
"result:= Default( T );" sollten helfen.
Es ist schon ein wenig schade, dass Delphi mit dem Wissen, dass T eine Klasse sein muss, nicht erschliessen kann, dass nil und default(T) das selbe meinen müssen...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:15 Uhr.
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