Eigenen Elementtyp in Liste injizieren
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Eigenen Elementtyp in Liste injizieren
Hallo!
Gibt es eine Möglichkeit einer eigenen Liste ähnlich TList ohne nochmalige Ableitung einer eigenen Klasse oder Ähnliches im Nachhinein einen Elementtyp einzuimpfen? In etwa so:
TMyList ist eine Liste mit Elementen einer Klasse TMyElement. Die Implementation der Liste soll nun unangetastet bleiben. Nun will ich die Liste aber mit einer von TMyElement abgeleiteten Klasse TMyNewElement benutzen. Wenn ich auf TList.Item[xy] zugreife, möchte ich kein Objekt vom Typ TMyElement, sondern vom Typ TMyNewElement bekommen. Ist das irgendwie realisierbar, indem das Listenelement nur als Interface implementiert wird oder so? Ich nehme mal an, dass die Implementierung des Interfaces auch mehr als das Interface fordert implementieren darf. Mit Generics müsste die Liste ja auch erst wieder abgeleitet werden...
Hintergrund: Ich möchte bei einer Komponntenentwicklung eine Liste integrieren, die die Elemente freigibt (und evtl. noch mehr Aktionen durchführt), bevor sie gelöscht werden, aber den endgültigen Elementtyp noch nicht kennt. Daher ist eine Ableitung eher ungünstig.
Gibt es eine Möglichkeit einer eigenen Liste ähnlich TList ohne nochmalige Ableitung einer eigenen Klasse oder Ähnliches im Nachhinein einen Elementtyp einzuimpfen? In etwa so:
TMyList ist eine Liste mit Elementen einer Klasse TMyElement. Die Implementation der Liste soll nun unangetastet bleiben. Nun will ich die Liste aber mit einer von TMyElement abgeleiteten Klasse TMyNewElement benutzen. Wenn ich auf TList.Item[xy] zugreife, möchte ich kein Objekt vom Typ TMyElement, sondern vom Typ TMyNewElement bekommen. Ist das irgendwie realisierbar, indem das Listenelement nur als Interface implementiert wird oder so? Ich nehme mal an, dass die Implementierung des Interfaces auch mehr als das Interface fordert implementieren darf. Mit Generics müsste die Liste ja auch erst wieder abgeleitet werden...
Hintergrund: Ich möchte bei einer Komponntenentwicklung eine Liste integrieren, die die Elemente freigibt (und evtl. noch mehr Aktionen durchführt), bevor sie gelöscht werden, aber den endgültigen Elementtyp noch nicht kennt. Daher ist eine Ableitung eher ungünstig.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Wenn du keine Generics benutzt, musst du ableiten oder besser TList kapseln. Für Generics brauchst du aber den FPC v.2.3.1.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Also du meinst, es gibt keine Möglichkeit im Nachhinein einen Elementtyp zu injizieren?
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 512
- Registriert: Mo 25. Aug 2008, 18:17
- OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
- CPU-Target: x86
- Wohnort: Chemnitz
Re: Eigenen Elementtyp in Liste injizieren
1. trunk ist schon bei 2.5.1 
2. theoretisch kann auch FPC 2.2 schon Generics

2. theoretisch kann auch FPC 2.2 schon Generics
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Damit man bei einer Liste immer mit einen bestimmten Typ arbeiten kann, müssen Typecasts zu Pointern durchgeführt werden, da Pascal sehr typensicher ist. TObjectList führt daneben nur ein paar Eigenschaften mit Bezug auf Objekte ein.
Wie die Typecasts durchgeführt werden ist eigentlich egal. Eine Liste zu kapseln ist der beste Weg, da TList keine virtuellen Methoden besitzt (damit schneller) und das überschreiben deshalb zu Leistungsverlust führt. Bei den Generics übernimmt der Compiler die "Code-Erzeugung" für die entsprechenden Typen; du musst sie nur nicht mehr alles explizit schreiben. Wenn du keine Generics benutzen möchtest/kannst, wäre es evtl. auch möglich das ganze durch Compiler-Macros und Include-Dateien durchzuführen. Generics sind aber definitiv einfacher zu benutzen, da sie Sprachbestandteil sind.
Wie die Typecasts durchgeführt werden ist eigentlich egal. Eine Liste zu kapseln ist der beste Weg, da TList keine virtuellen Methoden besitzt (damit schneller) und das überschreiben deshalb zu Leistungsverlust führt. Bei den Generics übernimmt der Compiler die "Code-Erzeugung" für die entsprechenden Typen; du musst sie nur nicht mehr alles explizit schreiben. Wenn du keine Generics benutzen möchtest/kannst, wäre es evtl. auch möglich das ganze durch Compiler-Macros und Include-Dateien durchzuführen. Generics sind aber definitiv einfacher zu benutzen, da sie Sprachbestandteil sind.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Mein Traum wäre eine Listbox, die eine Liste von Objekten hält. Sie baut darauf, dass jedes Objekt ein paar bestimmte Eigenschaften hat, um die Darstellung zu realisieren. Trotzdem bestimmt der "Benutzer" der Listbox, was diese Objekte sonst noch so alles speichern, um diese weiteren Werte (und Ereignisse etc) anderweitig zu nutzen. Daher denke ich, dass Generics nicht viel bringen, ich will ja nicht erst die Listbox spezialisieren, neu registrieren und dann erst verwenden können. Falls das nicht nötig ist, bitte ich um einen Wink mit dem Zaunspfahl.
Am Genialsten wäre es, wenn es eine Eigenschaft gäbe, der ich den Typ TMyNewElement übergebe, so dass Elemente vor ihrer Rückgabe von TMyElement auf den davon abgeleiteten eigenen Typ TMyNewElement gecastet werden. In Quelltext ausgedrückt (extrem quick´n´dirty):
Dass das so nicht geht ist mir bewusst, aber es erklärt mein unerreichbares Fernziel
Momentan habe ich die Listbox so programmiert, dass DrawItem ein Event OnItemNeeded wirft, welches alle erforderlichen Eigenschaften der Zeile vom "Nutzer" erfragt. Das ist sicherlich auch keine gute, aber immerhin erstmal eine Lösung...

Am Genialsten wäre es, wenn es eine Eigenschaft gäbe, der ich den Typ TMyNewElement übergebe, so dass Elemente vor ihrer Rückgabe von TMyElement auf den davon abgeleiteten eigenen Typ TMyNewElement gecastet werden. In Quelltext ausgedrückt (extrem quick´n´dirty):
Code: Alles auswählen
TMyList = class(TObject)
private
...
function GetElement(Index: Cardinal): TElementtype; // aus der Eigenschaft Elementtype
function SetElement(Index: Cardinal; AElem: TMyElement);
public
property Elementtype: TType // hier wird der Typ gespeichert. Er muss von TMyElement abgeleitet sein.
property Elements[Index: Cardinal]: TMyElement read GetElement write SetElement;
...
end;
function TMyList.GetElement(Index: Cardinal): TElementtype;
begin
result := TElementtype({Element aus der internen Liste vom Typ TMyElement}); // Typecast für den "Nutzer"
end;

Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Beiträge: 512
- Registriert: Mo 25. Aug 2008, 18:17
- OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
- CPU-Target: x86
- Wohnort: Chemnitz
Re: Eigenen Elementtyp in Liste injizieren
Wenn das dein Traum ist, dann nimm TVirtualStringTree ... das macht im Prinzip genau das. Du kannst egal was egal wie speichern und dann einfach OnGetText und Co nutzen, um aus deinen Daten die Strings etc. rauszufischen, die er anzeigen soll.
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Eigenen Elementtyp in Liste injizieren
Die Standard Liste, arbeitet mit TStringList, der hat eine Object Eigenschaft und Methoden: AddObject(...) z.b.
dort könntest du dein Objekt hinzufügen.
Eine eigene ListBox zu erstellen ist gar nicht so schwer. Wenn du möchtest könnte ich dir meinen ansatzt mal Hochladen. Unterstützt werden drei Anordnungs Modin.
Dürfte aber im Prinzip das sein, was du suchst, Fertig ist sie jedoch noch lange nicht. Aber für mein Projekt reicht das im Moment vollkommen aus. Eine Scroll Funktion gibt es auch schon.
dort könntest du dein Objekt hinzufügen.
Eine eigene ListBox zu erstellen ist gar nicht so schwer. Wenn du möchtest könnte ich dir meinen ansatzt mal Hochladen. Unterstützt werden drei Anordnungs Modin.
Dürfte aber im Prinzip das sein, was du suchst, Fertig ist sie jedoch noch lange nicht. Aber für mein Projekt reicht das im Moment vollkommen aus. Eine Scroll Funktion gibt es auch schon.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Ich kenne die Objects[]-Eigenschaft durchaus, aber ich hasse die ständigen Typecasts bei der Anwendung 
Bin auch grad beim Erstellen einer eigenen Listbox und eines Grids.

Bin auch grad beim Erstellen einer eigenen Listbox und eines Grids.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Eigenen Elementtyp in Liste injizieren
Es gibt da noch ein Trick, denn ich immer verwende:
Ob du nun eine TStringList oder direkt eine TObjectLIst verwendest spielt dabei keine Rolle:
Dadurch musst du zwar immer noch umwandeln, aber dafür wird der Code übersichtlicher und es erhöht die Sicherheit.
Andere Lösung währe: du leitest von der TObjectLIst ab und überschreibst einige Methoden z.b. die Add, Insert Methoden sowie die Items Eigenschaft.
Dadurch entfällt der TypCast zwar auch nicht, aber der Code wird übersichtlicher.
Meines Wissens musst du immer TypCasten. Es sei denn du verwendest eine neuere FPC Version und verwendest diese "Generics", aber dadurch entfällt die Code-Vervollständigung.
Es liegt leider in der Natur von "Object Pascal". In JavaScript wird z.b. der Typ Automatisch Angepasst je nach Typ der Variable.
Ob du nun eine TStringList oder direkt eine TObjectLIst verwendest spielt dabei keine Rolle:
Code: Alles auswählen
property myItems[aIndex:Integer]:TMyItem read GetMyItem
GetMyItem(...)
result:=fMyList[aindex] as TMyItem
Andere Lösung währe: du leitest von der TObjectLIst ab und überschreibst einige Methoden z.b. die Add, Insert Methoden sowie die Items Eigenschaft.
Dadurch entfällt der TypCast zwar auch nicht, aber der Code wird übersichtlicher.
Meines Wissens musst du immer TypCasten. Es sei denn du verwendest eine neuere FPC Version und verwendest diese "Generics", aber dadurch entfällt die Code-Vervollständigung.
Es liegt leider in der Natur von "Object Pascal". In JavaScript wird z.b. der Typ Automatisch Angepasst je nach Typ der Variable.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Das bedeutet alles immer entweder Veränderungen (Ableitung, Spezialisierung, Kapselung) an der Originalklasse oder Typcasting beim Verwenden der Originalklasse. Ergo: Originalklasse direkt verwenden und dabei keinen Typecast verwenden müssen ist nicht machbar. Das wäre mein Ziel gewesen.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Eigenen Elementtyp in Liste injizieren
Nein ! Es gebe da noch eine Möglichkeit:Ergo: Originalklasse direkt verwenden und dabei keinen Typecast verwenden müssen ist nicht machbar. Das wäre mein Ziel gewesen.
Du erstellst dir ein Array und machst was die TObjectList machst. Genau für deine Klasse. Aber das währe dann nur für deine ListBox Praktisch. Weißt du wie ich meine ?
Nur so brauchst du nicht Typ-Casten.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 462
- Registriert: Mi 30. Jul 2008, 13:11
- OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
- CPU-Target: 32Bit
- Kontaktdaten:
Re: Eigenen Elementtyp in Liste injizieren
Wenn ich dich richtig verstehe, meinst du meine Listbox genau an den Typ anzupassen, für den ich sie verwenden will. Das ist auch wieder nicht, was ich will. Ich wollte tatsächlich den Typ dynamisch einimpfen. Das ginge denke ich höchstens irgendwie über RTTI, aber selbst damit wüsste ich nicht wie.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Eigenen Elementtyp in Liste injizieren
Ich glaube hier überschätzt du die RTTI. Sie kann viel, aber ich bin mir fast sicher das sie da nicht kann.Das ginge denke ich höchstens irgendwie über RTTI, aber selbst damit wüsste ich nicht wie
Ich sehe in deinen Fall nur drei Lösungen:
01: Du machst es über Typ-Casten
02: Du erstellst dir eine eigene TObjectList. Die TObjectList ist Eigentlich auch nur ein einfacher Array der durch praktische Methoden wie Add und Delete erweitert wurde, wodurch der Zugriff auf ein Array leichter Wird. Dadurch verliest du aber die "Wiederverwendtbarkeit". Du könntest es aber auch so machen wie die VST. Über eine "Doppelt Verkette Pointer Liste". Dann dauert zwar das durchsuchen, aber dafür ist das Hinzufügen und Löschen einfacher, je nach dem was du möchtest. Du müsstest Aber Praktisch Diese Liste auch an deine LIstBox Anpassen.
03: Ich habe mal eine Möglichkeit gesehen, wo ich den Namen leider vergessen habe. Entweder war es über "Generics" oder über "Kompilier" Steueranweisungen darüber wurde glaube ich eine Technik Simuliert die in C++ üblich ist ich meine Templets oder so., aber egal was es war, du verliest die "Automatische Code-Vervollständigung"(STRG+Leertaste).
Ich hänge hier mal meine eigene ListView an, die ist aber noch nicht Fertig, aber Eventuell Hilft sie dir. Es währe Möglich das ich das Projekt weiter Entwickele, aber im Moment jedenfalls nicht.
Es gibt ein Beispiel Programm über die F Tasten kannst du die Ansicht beeinflussen, es gibt drei Stück zur auswahl:
ag_Hori So wie in der ListView mit dem Style: VSIcon
ag_Verti So wie eine ListBox
AG_OneLine Alles in einer Zeile
- Dateianhänge
-
plListView.zip
- (1.82 MiB) 91-mal heruntergeladen
MFG
Michael Springwald
Michael Springwald