Autor Beitrag
sunnyandy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47



BeitragVerfasst: So 11.11.07 21:15 
Hallo,

ich habe mittels zweier Interfaces das Observer-Pattern implementiert. Bei einer Änderung führt das Observable bei dem Beobachter die Methode Aktualisieren(Sender: TObject) aus. Dort wird immer eine Referenz auf die eigene Klasse mit übergeben.

Nun möchte ich im Observer überprüfen, von welcher Klasse die Aktualisieren Methode aufgerufen wird (Es kann ja mehrere Observable geben). Ich möchte wissen, ob die beobachtbare Klasse (Observable) ein FilterFrame ist (Meine FilterFrames implementieren nämlich IFilterFrame). "IS" kann man so wie es aussieht aber nicht auf Interfaces anwenden.
Wie kann ich hier prüfen, ob die übergebene Klasse IFilterFrame implementiert?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
{*
  Observer-Methode.
}

procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
begin
  if Sender is IFilterFrame then
  ...

end;


Sonst geht es doch mit Klassen wunderbar:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
begin
  if Sender is TMeinObject then
  begin
    (Sender as TMeinObject).Methode1;
    ...
  end;

end;


Danke im Voraus!
Andy
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: So 11.11.07 22:55 
user profile iconsunnyandy hat folgendes geschrieben:
Nun möchte ich im Observer überprüfen, von welcher Klasse die Aktualisieren Methode aufgerufen wird (Es kann ja mehrere Observable geben). Ich möchte wissen, ob die beobachtbare Klasse (Observable) ein FilterFrame ist (Meine FilterFrames implementieren nämlich IFilterFrame). "IS" kann man so wie es aussieht aber nicht auf Interfaces anwenden.
Wie kann ich hier prüfen, ob die übergebene Klasse IFilterFrame implementiert?


Der IS Operator funktioniert bei Interfaces nur, wenn das Interface eine GUID hat (Ctrl-Alt-G oder war's Shift-Ctrl-G im Editor zum Erzeugen).

ausblenden Delphi-Quelltext
1:
2:
3:
type
  IFilterFrame = interface [guid hier]
    ...


twm
sunnyandy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47



BeitragVerfasst: So 11.11.07 23:13 
Hallo,

danke für deine Antwort!
Ich habe es ausprobiert, es funktioniert aber leider nicht.
Fehler: Operator ist auf diesen Operandentyp nicht anwendbar

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
interface
  uses
    Observable;

  type IFilterFrame = interface(IObservable)
  ['{805F0FA9-5665-4020-BA24-0FADBBDE28EB}']
    procedure AktualisiereAnzahl(AnzahlSelektion: integer; AnzahlAlle: integer);
  end;
...


Das müsste so richtig sein oder?
sunnyandy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47



BeitragVerfasst: Mo 12.11.07 01:09 
Ich denke ich kann das nun folgendermaßen abfragen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Supports(Sender, IFilterFrame) then
  begin
    FilterFrame := (Sender as IFilterFrame); // <- Funktioniert nicht!
    FilterFrame.DoSomething;
  end;


Wie bekomme ich denn den TypeCast von TObject zum Interface hin? Es will einfach nicht funktionieren.
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Mo 12.11.07 19:22 
user profile iconsunnyandy hat folgendes geschrieben:
Ich denke ich kann das nun folgendermaßen abfragen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Supports(Sender, IFilterFrame) then
  begin
    FilterFrame := (Sender as IFilterFrame); // <- Funktioniert nicht!
    FilterFrame.DoSomething;
  end;


Wie bekomme ich denn den TypeCast von TObject zum Interface hin? Es will einfach nicht funktionieren.


Ohne es jetzt getestet zu haben:
ausblenden Delphi-Quelltext
1:
2:
if S_OK = (Sender as TInterfaceObject).QueryInterface(IFilterFrame, FilterFrame) then
  FilterFrame.DoSomething;


twm
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Mo 12.11.07 20:23 
user profile iconsunnyandy hat folgendes geschrieben:
Ich denke ich kann das nun folgendermaßen abfragen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Supports(Sender, IFilterFrame) then
  begin
    if (Sender is IFilterFrame) then 
      FilterFrame.DoSomething;
  end;


Wie bekomme ich denn den TypeCast von TObject zum Interface hin? Es will einfach nicht funktionieren.

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Mo 12.11.07 20:30 
user profile iconMrSaint hat folgendes geschrieben:
user profile iconsunnyandy hat folgendes geschrieben:
Ich denke ich kann das nun folgendermaßen abfragen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Supports(Sender, IFilterFrame) then
  begin
    if (Sender is IFilterFrame) then 
      FilterFrame.DoSomething;
  end;


Wie bekomme ich denn den TypeCast von TObject zum Interface hin? Es will einfach nicht funktionieren.


Aeh? Und die Zuweisung von FilterFrame erfolgt durch Magie??

twm
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Mo 12.11.07 20:32 
puh, sorry.... man sollte mal genau lesen ;) Einfach meinen Quark hier vergessen :D

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Mo 12.11.07 22:34 
Wenn man mit Interface Variablen arbeitet verbergen sich dahinter auch immer nur normale Klassen allerdings darf man sie solange man sie als interface anspricht nur mit den Interface Methoden arbeiten alla:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type myinterface = interface(IUnknown)
 function getref:class of TObject;
end;

type myclass1 = class(TObject,Myinterface)

end;

//und die anderen myclass2 identisch/analog

implementation

function TMyclass1.getref:class of TObject;
begin
  result:=self.classtype;
end;


Wie man hier sieht ist das etwas trickey, da interfaces nur Methoden definieren und keine Variablen selbst haben deshalb die Klassenreferenz selbst mitschleppen. Die könntest du jetzt direkt vergleichen so alla:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
   klassentyp:=myinterfacevar.getref;
   case klassentp of 
     myclass1:...;
     myclass2:...;
   end;


Was aber ebenfalls geht ist, da sich hinter jedem Interface ein Object verbirgt es einfach als Object ansprechen das heißt auf TObject casten und dann classtype benutzen alla:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
  if TObject(myinterfacevar) is myclass1 
  then begin
     //...
  end;


//Edit:

Wenn du sowieso schon weißt, dass deine Klasse dieses Interface unterstützt dann sollte es ja auch reichen zu überprüfen welche Klasse es ist mit dem is-Operator. So heißt es auch in einer Zeile bei dir. Falls es da partout keinen Befehl gibt kann man da auch einen Workaround machen, da diese Information meistens bei Compilierzeit feststehen sollte kannst du einfach eine Liste mit Klassen machen welche dies und das unterstützen und mit der vergleichen.

Was auch möglich wäre alle Objekte ein Interface Iinterfacechecklist implementieren zu lassen die immer ja nein zurückgeben wenn sie es unterstützen.
sunnyandy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47



BeitragVerfasst: Di 13.11.07 00:26 
Hallo,

vielen Dank für eure Antworten!
man kann mithilfe "Supports" gleich einen Verweis auf das Objekt herstellen...
Diese Lösung hier funktioniert wunderbar:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TFrameKundenliste.Aktualisieren(Sender: TObject);
var
  FilterFrame: IFilterFrame;
begin
  if Supports(Sender, IFilterFrame, FilterFrame) then
    FilterFrame.DoSomething; 
  ...


Es klappt :-)