2010-09-12 4 views
9

Gibt es eine Möglichkeit, die Eigenschaften einer Schnittstelle mit Rtti zu erkunden?Delphi Rtti: Eigenschaften von Schnittstellen erforschen?

Der folgende Code funktioniert nicht:

procedure ExploreProps; 
var 
    Ctx: TRttiContext; 
    RttiType: TRttiType; 
    RttiProp: TRttiProp; 
begin 
    RttiType := Ctx.GetType(TypeInfo(IMyInterface)); 
    for RttiProp in RttiType.GetProperties do 
    Writeln(RttiProp.ToString); 
end; 

Hat jemand eine Lösung, wie diese richtig zu tun?

Antwort

4

Schnittstellen sind Sammlungen von Funktionen. Sie haben Eigenschaften nicht wirklich wie Objekte; Das ist nur ein bisschen syntaktischer Zucker, den der Compiler für Sie hinzufügt, um es einfacher zu machen, Code für sie zu schreiben. Der Unterschied besteht darin, dass Objekte bei Objekten den kontrollierten Zugriff auf private und geschützte Mitglieder ermöglichen, während bei den Schnittstellen alle Mitglieder öffentlich sind, sodass die Eigenschaften nicht benötigt werden.

+0

Ok TInterfacedObject, aber ein Schnittstellen-Methoden zu erforschen funktioniert auch nicht ... Nur ersetzt die for-Schleife mit RtttiType.GetMethods, immer noch keine Ergebnisse. –

+4

@Christian: Ich habe mir gerade den Code für das RTTI-System angeschaut, und viele Schnittstellen in den Standardbibliotheken sind eingerichtet, für die keine RTTI generiert wurde. Ich bin mir nicht sicher, was die Regeln sind, um Extended RTTI für Interface-Typen zu generieren, da es sich von der Generierung von Extended RTTI für Klassen oder Datensätze unterscheidet. Vielleicht könnten Barry Kelly oder Allen Bauer diese Frage beantworten? –

+0

Für einen Schnittstellentyp muss '{M +}' angewendet werden, damit 'TRttiType.GetMethods()' die Methoden der Schnittstelle melden kann. –

1

Wie ich weiß, gibt es keine Unterstützung für normale Schnittstellen. Sie könnten {$ M +} hinzufügen und es dann erneut versuchen.

-1

späte Antwort, aber Sie könnten Ihre Interfaces TObject, z.

RttiType := Ctx.GetType(TObject(IMyInterface).ClassInfo); 
+0

Das ist falsch und gefährlich. Aufgrund des Speicherlayouts können Schnittstellen nicht in Objekte umgewandelt werden. Sie müssten der Oberfläche eine Funktion hinzufügen, um zum Objekt zurückzukehren (wie in der Antwort von @FLICKER). –

2

diese Funktion in Ihrer Schnittstelle

function GetObject: TObject; 

und implementieren sie in der Klasse hinzufügen. die Verwendung der GetObject-Funktion mit RTTI-Routinen

var 
    obj: IPerson; 
begin 
    obj := TPerson.Create; 
    Count := GetPropList(obj.GetObject.ClassInfo, tkAny, @List); 
end; 

Bitte beachten Sie, dass Ihre Klasse von TInterfacedPersistent vererbt werden sollte nicht

TPerson = class(TInterfacedPersistent, IPerson) 
Verwandte Themen