Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Prüfen, ob Klasse ein Interface implementiert?
sunnyandy - So 11.11.07 21:15
Titel: Prüfen, ob Klasse ein Interface implementiert?
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?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TFrameKundenliste.Aktualisieren(Sender: TObject); begin if Sender is IFilterFrame then ...
end; |
Sonst geht es doch mit Klassen wunderbar:
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 - So 11.11.07 22:55
Titel: Re: Prüfen, ob Klasse ein Interface implementiert?
sunnyandy 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).
Delphi-Quelltext
1: 2: 3:
| type IFilterFrame = interface [guid hier] ... |
twm
sunnyandy - 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
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 - Mo 12.11.07 01:09
Ich denke ich kann das nun folgendermaßen abfragen:
Delphi-Quelltext
1: 2: 3: 4: 5:
| if Supports(Sender, IFilterFrame) then begin FilterFrame := (Sender as IFilterFrame); FilterFrame.DoSomething; end; |
Wie bekomme ich denn den TypeCast von TObject zum Interface hin? Es will einfach nicht funktionieren.
dummzeuch - Mo 12.11.07 19:22
sunnyandy hat folgendes geschrieben: |
Ich denke ich kann das nun folgendermaßen abfragen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if Supports(Sender, IFilterFrame) then begin FilterFrame := (Sender as IFilterFrame); 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:
Delphi-Quelltext
1: 2:
| if S_OK = (Sender as TInterfaceObject).QueryInterface(IFilterFrame, FilterFrame) then FilterFrame.DoSomething; |
twm
MrSaint - Mo 12.11.07 20:23
sunnyandy hat folgendes geschrieben: |
Ich denke ich kann das nun folgendermaßen abfragen:
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. |
dummzeuch - Mo 12.11.07 20:30
MrSaint hat folgendes geschrieben: |
sunnyandy hat folgendes geschrieben: | Ich denke ich kann das nun folgendermaßen abfragen:
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 - Mo 12.11.07 20:32
puh, sorry.... man sollte mal genau lesen ;) Einfach meinen Quark hier vergessen :D
Allesquarks - 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:
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;
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:
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:
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 - 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:
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 :-)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!