![]() |
Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Hi!
Ich hab eine TComponentList voll mit unterschiedlichen Objekten, die alle garantiert ein IMyInterface haben. Nun will ich über die ComponentList für ein einzelnes Objekt einen Wert über das Interface ändern. Wie geht das? IMyInterface(SelectedObjects.Items[i]).x := 1; --> Inkompatible Typen: 'IMyInterface' und 'TPersistent' bla: IMyInterface; bla := SelectedObjects.Items[i]; bla.x := 1; --> Inkompatible Typen: 'IMyInterface' und 'TPersistent' |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Ich bin mir nicht ganz sicher, aber es wäre durchaus möglich, dass das nicht geht - du musst eventuell wirklich auf eine Klasse casten, die das Interface implementiert - das kann theoretisch auch eine einfache Basisklasse sein, die nur das Interface implementiert - eventuell sogar alle Methoden als abstrakt. Von der leitest du dann alles andere, was das Interface implementiert, ab.
Aber ich arbeite nicht sehr viel mit Interfaces, könnte also sein, dass das auch anders möglich ist. |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Wenn das stimmt, dann wären Interfaces meiner Meinung nach kompletter Unsinn:
Ich habe einen TButton und ein TEdit, die beide die Prozedur .FooBar bekommen sollen. Wie soll ich denn aus den Beiden eine gemeinsame Basisklasse machen? Weil Mehrfachvererbung in Delphi nicht geht, gibt es ja Interfaces. Ich fange aber leider eben erst mit an und kapier das noch nicht so ganz :/ Edit: OMG, alle Delphi-Interface-Tutorials die ich bisher gefunden habe, gehen davon aus, dass mir schon zur Entwicklungszeit bekannt ist, mit was für einem Objekt ich gerade arbeite. Klar, dann funktioniert das, mit Typecast auf TMyObject(foo).bla. Tjo, aber wenn das Objekt aus der ComponentList nun von der Klasse TFoo oder TBar ist, die auch das Interface haben bringt mir das afaik nix, weil der ja durch den Typecast auf die falsche Klasse den falschen Speicherbereich ausliest... |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Eigentlich (sofern es sich wirklich um eine TComponentList handelt) sollten die Elemente der Liste vom Typ TComponent sein, der wiederum IInterface implementiert und somit auf andere Interfaces castbar (Vorsicht: denglisch) ist. Die Fehlermeldung bzgl. TPersistent irritiert mich da ein wenig.
Zu deinem Nachtrag: du musst nicht wirklich den Typ des Objekts wissen, du musst nur eine gemeinsame Basisklasse wissen, die IInterface implementiert. |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Zitat:
Zitat:
Bei TComponent kannst du den "as" Operator nutzen:
Delphi-Quellcode:
(SelectedObjects.Items[i] as IMyInterface).x := 1;
Wenn du jedoch mit TPersistent arbeitest, dass kein IInterface implementiert, also auch keine QueryInterface Methode besitzt, musst du auf die Supports() Funktionen ausweichen.
Delphi-Quellcode:
Das ist ziemlich Umständlich, da hier der "as"-Operator nicht funktioniert weil TPersistent kein IInterface implementiert. Mit TInterfacedPersistent würde das kein Problem sein.
var
bla: IMyInterface; begin if Supports(SelectedObjects.Items[i], IMyInterface, bla) then bla.x := 1; end; Kleine Hilfsfunktion wenn du einen Einzeiler haben willst.
Delphi-Quellcode:
function IntfCast(Instance: TObject; const IID: TGUID): IInterface;
begin if not Supports(Instance, IID, Result) then raise EIntfCastError.CreateRes(@SIntfCastError); end; var Persistent: TPersistent; begin Persistent := Irgendwas; IMyInterface(IntfCast(Persistent, IMyInterface).x := 1; end; |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Ok, zur Verteidigung von Delphi und Schlamperei meinerseits muss natürlich noch gesagt werden, dass dies (hab den Code ein paar Wochen nicht gesehen) keine einfache TComponentList ist, sondern vom Typ TLMDDesignObjects, was zwar auch eine Liste für Komponenten, aber keine TComponenList in diesem Sinne ist.
var comp: TComponent; begin comp := TComponent(SelectedObjects[i]); (comp as IMyInterface).DS := 1; ^-- scheint zu gehen (TComponent(SelectedObjects[i]) as IMyInterface).DS := 1; ^-- scheint auch zu gehen So, schon mal sehr gut dass wir soweit sind, Danke erstmal. Diese Zeile kann man aber auf die Schnelle nicht mehr vereinfachen, denke ich mal? Der "as" Operator prüft doch zur Laufzeit alle Objekte, ob die auch wirklich das Interface haben, sonst gibt's Exception. Korrekt, oder? Danke nochmal für die Tips! |
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Zitat:
|
Re: Inkompatible Typen: 'IMyInterface' und 'TPersistent'
Ok, Danke an Alle. Thema erfolgreich abgehakt. Gute N8.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:40 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 by Thomas Breitkreuz