Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Typecast von TObject zum Interface? (https://www.delphipraxis.net/103180-typecast-von-tobject-zum-interface.html)

sunny-andy 11. Nov 2007 22:58


Typecast von TObject zum Interface?
 
Hallo liebe Leute,

seit Stunden suche ich eine Möglichkeit, ein TObject in ein Interface zu typecasten.

Ich habe für das Observer-Pattern eine Methode namens Aktualisieren, welche ein Objekt mitliefert.
Manchmal implementiert das mitgelieferte Objekt ein Interface (IFilterFrame), und dessen Methoden möchte ich dann gern ausführen:

Delphi-Quellcode:
{*
  Observer-Methode.
}
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
var
  FilterFrame: IFilterFrame;
begin
  if Supports(Sender, IFilterFrame) then
  begin
    FilterFrame := (Sender as IFilterFrame); // <- Funktioniert nicht!
    FilterFrame.DoSomething;
  end;
Was ich auch probiert habe, es gibt nur Fehler.
Habt ihr vielleicht einen Tipp für mich?

Danke!
Andy

cruiser 12. Nov 2007 02:34

Re: Typecast von TObject zum Interface?
 
Rein theoretisch müsste das gehn...

Delphi-Quellcode:
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
var
  FilterFrame: IFilterFrame;
begin
  if Supports(Sender, IFilterFrame, FilterFrame) then
    FilterFrame.DoSomething;

{...}

SirThornberry 12. Nov 2007 06:30

Re: Typecast von TObject zum Interface?
 
du schreibst das es nicht funktioniert und nur fehler gibt. Welche Fehler gibt es denn? Gibt es die Fehler erst beim ausführen oder schon beim compilieren?

xaromz 12. Nov 2007 08:20

Re: Typecast von TObject zum Interface?
 
Hallo,

ich gebe mal einen Tipp ab: Du hast Deinem Interface keinen GUID verpasst. Das benötigt Delphi aber für "Supports" und "as". Übrigens muss bei meinem Delphi "Supports" nicht mit dem Interface, sondern mit dem GUID aufgerufen werden.

Gruß
xaromz

efknarf 12. Nov 2007 08:33

Re: Typecast von TObject zum Interface?
 
Hallo,

Filterframe ist eine Variable des Typs IFrame, welche jedes beliebige Object speichern kann, das diesen Interface-Typ implementiert. Nun nehme ich an, daß du feststellen möchtest, ob das Object diese Schnittstelle unterstützt. Schaue dazu mal in der Hilfe unter:

* TObject.GetInterfaceEntry
* TObject.GetInterface
* TObject.GetInterfaceTable

Gruß

Frank

//Edit: Jedes Interface hat eine GUID. Falls bei der Deklaration keine angegeben wird, dann erstellt diese der Compiler.
//Edit2: Nachlesen konnte ich, daß ür eine GUID auch der Name des Interfaces angegeben werden kann. Der Compiler ersetzt diesen dann durch die GUID.

sunny-andy 12. Nov 2007 08:50

Re: Typecast von TObject zum Interface?
 
Zitat:

Zitat von cruiser
Rein theoretisch müsste das gehn...

Delphi-Quellcode:
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
var
  FilterFrame: IFilterFrame;
begin
  if Supports(Sender, IFilterFrame, FilterFrame) then
    FilterFrame.DoSomething;

{...}

Hallo, danke für eure Antworten. Das GUID hatte ich von Anfang an drin.
Die obige Antwort ist genau das, was ich gesucht habe. Es funktioniert wurderbar, dankeschön!
:hi:

Elvis 12. Nov 2007 08:55

Re: Typecast von TObject zum Interface?
 
Zitat:

Zitat von efknarf
//Edit: Jedes Interface hat eine GUID. Falls bei der Deklaration keine angegeben wird, dann erstellt diese der Compiler.

Nein, wird nicht gehen.
Delphi-Quellcode:
program Blabla;

{$APPTYPE CONSOLE}

type
  IMyInterface = interface
  end;

  TMyClass = class(TInterfacedObject, IMyInterface)
  end;

var
  objRef : TMyClass;
  intfRef : IMyInterface;
begin
  intfRef := objRef as IMyInterface;
end.
Zitat:

//Edit2: Nachlesen konnte ich, daß ür eine GUID auch der Name des Interfaces angegeben werden kann. Der Compiler ersetzt diesen dann durch die GUID.
Ja, der Typ eines Interfaces kann als GUID benutzt werden. (Das nutze ich zum Bleistift um Factories oder Services zu verwalten)
Aber auch das geht nur, wenn das Interface eine GUID bekam.
Tut ja auch nicht weh, Ctrl + Shift + G und schon hat man eine GUID.

efknarf 12. Nov 2007 09:20

Re: Typecast von TObject zum Interface?
 
Hallo,

:wall: Stimmt! Mein Fehler. Dennoch sollte es mit der Funktion TObject.GetInterface gehen. Habe es eben ausprobiert.

Gruß

shmia 12. Nov 2007 17:33

Re: Typecast von TObject zum Interface?
 
:warn: Das Mischen von Objekten und Interfaces kann unangenehme Folgen haben!!
Delphi-Quellcode:
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
var
  FilterFrame: IFilterFrame;
begin
  if Supports(Sender, IFilterFrame, FilterFrame) then
  begin
    // intern wurde jetzt FilterFrame.AddRef aufgerufen
    // der Referenzzähler steht jetzt auf 1

    FilterFrame.DoSomething;
  end;

// jetzt gerät FilterFrame out-of-scope
// also wird FilterFrame.Release aufgerufen
// dann steht der Refernzzähler auf 0 und das Objekt wird freigegeben !!!
// es sei denn, man hat spezielle Maßnahmen getroffen, dass das nicht passiert
end;

Elvis 12. Nov 2007 18:04

Re: Typecast von TObject zum Interface?
 
Zitat:

Zitat von shmia
:warn: Das Mischen von Objekten und Interfaces kann unangenehme Folgen haben!!

In diesem Fall (bzw. jedem in dem Supports benutzt wird) schon.
Oft hat man aber eine Objektreferenz, bei der der Typ bereits ein bestimmtes Interface unterstützt.
Dann kann man problemlos die Objektreferenz an Methoden übergeben, die einen Interfacezeiger als "const" bekommen.
Delphi-Quellcode:
class procedure Miep.Mööp(const aInterfaceRef : IMyInterface);
begin
  aInterfaceRef.DoSomething();
end;

var
  objectRef : TMyClass;
begin
  Miep.Mööp(objectRef);
Natürlich klappt das nicht mehr, wenn die Methode irgendwelche unkoscheren Dinge damit anstellt. (Zuweisen von Feldern, Weitergabe an Methode ohne "const", ...)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:05 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