Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie dynamischer Vorfahr für generische Klasse? (https://www.delphipraxis.net/149136-wie-dynamischer-vorfahr-fuer-generische-klasse.html)

himitsu 15. Mär 2010 12:27

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von Uwe Raabe
Klar, aber dann schreib doch einfach ...

OK, dann eben ein anderes Beispiel:
Delphi-Quellcode:
procedure Proc(SL: TStrings);
begin
end;

var X: TListNode<TStringList>;

Proc(X); // geht auch nicht, da keine Stringliste
Und sag jetzt nicht,
Zitat:

Klar, aber dann schreib doch einfach
Delphi-Quellcode:
Proc(X.data);

denn ich will ja das ganze X übergeben können und nicht nur den einen Teil des "Vorfahren".
Außerdem finde ich es mit den .data im Code dann etwas unübersichtlich/umständlich.

Stevie 15. Mär 2010 12:39

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Ich frag mich gerade, wie die Implementierung deiner Klasse aussehen soll, wenn du dort nichtmal weißt, wovon sie abgeleitet ist. Dazu müsstest du doch zumindest einen Constraint angeben, oder nicht?

himitsu 15. Mär 2010 12:46

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von Stevie
Ich frag mich gerade, wie die Implementierung deiner Klasse aussehen soll, wenn du dort nichtmal weißt, wovon sie abgeleitet ist. Dazu müsstest du doch zumindest einen Constraint angeben, oder nicht?

Für die Verwaltung ist nur der aktuelle Typ wichtig und nicht irgendein Vorfahr. (zumindestens in meinem Fall)

HERMES 15. Mär 2010 12:57

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Wenn du sagst, deine Basisklasse ist nicht bekannt, dann meist du damit, dass diese auch eine generische Klasse ist? Oder wie istdas sonst zu verstehen


Zitat:

Klar, aber dann schreib doch einfach ...
Delphi-Quellcode:
procedure Proc(SL: TListNode<TStringList>);
begin
end;

var X: TListNode<TStringList>;

Proc(X); // geht auch nicht, da keine Stringliste
oder allgemeiner
Delphi-Quellcode:
procedure Proc(SL: TListNode<Y>);
begin
end;

var X: TListNode<TStringList>;

Proc(X); // geht auch nicht, da keine Stringliste

Stevie 15. Mär 2010 13:00

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von Stevie
Ich frag mich gerade, wie die Implementierung deiner Klasse aussehen soll, wenn du dort nichtmal weißt, wovon sie abgeleitet ist. Dazu müsstest du doch zumindest einen Constraint angeben, oder nicht?

Für die Verwaltung ist nur der aktuelle Typ wichtig und nicht irgendein Vorfahr. (zumindestens in meinem Fall)

Mit Vorfahr meinte ich den Typparameter T bei deinem eingangs erwähnten Konstrukt, welcher ja der Vorfahr dieser Klasse wäre:
Delphi-Quellcode:
TMyClass<Ancestor: class> = class(Ancestor)
Welche Gemeinsamkeiten hätte denn TMyClass<TForm> mit TMyClass<TFoo> (bewusst nicht definierte Klasse gewählt) außer, dass beide explizit auf mindestens TMyClass<TObject> umgecastet werden könnten? Beziehungsweise, wozu muss der Typparameter der Vorfahr der Klasse sein? Nur, damit du ein Object davon an eine Methode übergeben kannst, die TForm bzw TFoo akzeptiert? Das geht auch anders.

Phoenix 15. Mär 2010 13:06

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von himitsu
Denn diese Klasse soll selber nur eine gewisse Funktionalität für andere, davon abgeleitete Klassen bereitstellen, aber ich wollte den anderen Klassen nicht die Möglichkeit nehmen, jeweil einen "anderen" Vorfahren zu nutzen.

Dafür sind Generics aber nicht gedacht.
Was Du haben willst sind Interfaces. Und um Methoden zur Verfügung zu stellen benutzt Du dann Extension Methods (Class helper) auf diesem Interface.

Somit können alle von ihrer gewünschten Basisklasse ableiten, das Interface implementieren (das kann auch einfach leer sein, wenn es nur um Methoden geht) und aufgerufen werde diese Methoden über die Class helper auf dem Interface.

himitsu 15. Mär 2010 13:33

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von Phoenix
Dafür sind Generics aber nicht gedacht.

Och menno. :cry:

Nja, ich hab mir hier halt ein Problem geschaffen
und versuche dafür nun eine "nette" Lösung zu finden.


Nja, ich werde noch etwas rumspielen ... mal sehn, vielleicht finde ich ja noch eine andere Lösung, außer dem Interface.



Ich spiele grad so ein bissl rum und probiere mehreres aus.

So war ich erstmal bei den "kleineren" Records gelandet, aber so wie es aussieht, werde ich wohl oder übel auf Klassen umsteigen müssen, weswegen ich dann auf das oben genannte "Problem" gekommen bin.

Delphi-Quellcode:
PMyRec = ^TMyRec<Typ: record>; // <<< geht natürlich nicht
                                //     aber das war ja klar
TMyRec<Typ: Record> = record      
  type PTyp = ^Typ;            // <<< geht
  {...}
end;
Allerdings geht auch das nicht, obwohl hier Typ ja bekannt wäre.
Delphi-Quellcode:
TMyRec<Typ: record> = record
  type PMyRec = ^TMyRec<Typ>; // <<< geht nicht
    PTyp = ^Typ;              // <<< geht
  {...}
end;
Wie soll man da einen Pointer deklarieren, welchen auch der generische Teil kennt?

OK, außer man macht es umständlicher extern,
welches aber nicht unbedingt eine "fehlerunanfälligere" Deklaration erfordert.
Delphi-Quellcode:
TMyRec<Typ: record; PRec> = record
  type PMyRec = PRec;
    PTyp = ^Typ;
  {...}
end;

PTest = ^TTest;
TTest = TMyRec<Integer, PTest>;
Und da Records keine Vererbung kennen, kann man hier ja keinen genaueren Typen festlegen, welcher dann ein "Value" kennt:
Delphi-Quellcode:
TMyRec<Typ: record> = record
  x: Typ;
  function Test: Integer;
end;

function TMyRec<Typ>.Test: Integer;
begin
  Result := X.Value; // <<< geht nicht
end;
Selbst wenn sichergestellt ist, daß der Record "Typ" einen Wert "Value" besietzt, geht dieses nicht,
da der Compiler dennoch meckert, daß "Value" nicht bekannt sei.

[add]
Und Generics für Helper gehn leider auch nicht.
Delphi-Quellcode:
TMyRec<Typ: Record> = Record Helper for Typ
  ...
end;

TMyCls<Typ: Class> = Class Helper for Typ
  ...
end;

Phoenix 15. Mär 2010 14:30

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Wieso bist Du so auf Generics versessen?
Die haben zwar ihre Daseinsberechtigung, sind aber kein Allheilmittel.

Was willst Du denn eigentlich *genau* machen bzw. welches Problem hast Du Dir geschaffen was Du 'nett' Lösen willst?
Vielleicht finden wir einen anderen / besseren Lösungsansatz der nicht das vergewaltigen von Sprachkonstrukten zum Inhalt hat? ;-)

himitsu 15. Mär 2010 15:14

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Zitat:

Zitat von Phoenix
Wieso bist Du so auf Generics versessen?

Ich bin ein Playboy ... äääääää, ein Spieljunge/Spielkind
und "neue" Dinge müssen gründlich ausprobiert werden.

Ja, und ich suche gern die Grenze des Möglichen und wenn möglich überschreite ich sie gerne mal.

Wenn es nicht klappt, dann geht's halt nicht und ich löse es anders/normal. :angel2:


Die Verwaltung einer mehrfach verketteten Liste ist ja nicht unbedingt sooooo einfach.
Für sowas hab ich jetzt erstmal ein Template, welches man verwenden/anpassen könnte.
Nun wollte ich das Ganze aber mal versuchen generisch zu lösen, so daß man es direkt einbinden und ohne Änderung verwenden könnte.

Uwe Raabe 15. Mär 2010 15:54

Re: Wie dynamischer Vorfahr für generische Klasse?
 
Ist nur meine Meinung, aber ich halte es für keine gute Idee, die strukturelle Verknüpfung von Objekten in die Klassen zu verlagern. Das schränkt die Verwendbarkeit m.E. zu stark ein.

Beispiel: Nehmen wir die Klasse TStringList und leiten daraus einen TStringListNode ab, der dann für die verkettete Liste zuständig ist. Natürlich kann ich jetzt sowas wie Node is TStringList abfragen, aber was ist mit einer von TStringList abgeleiteten Klasse (z.B. TExtendedStringList)? Diese müsste eine neue Node-Ableitung bekommen TExtendedStringListNode. Das könnte wohl auch der Anlass zu deiner Frage gewesen sein.

Nehmen wir nun mal an, es gäbe diesen Node-Generic. Nun brauchst du aber die Objekte nicht in einer verketten Liste, sondern in einer Baumstruktur. Geht aber nicht, weil du nicht einfach aus den ListNode-Instanzen TreeNode-Instanzen machen kannst.

Wenn du die Struktur-Elemente aus den Klassen heraus hälst, gewinnst du wesentlich mehr Spielraum (Playboy!).


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Seite 2 von 3     12 3      

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