Der Code, den Sie in Ihrer Frage angezeigt haben, ist vollkommen in Ordnung (vorausgesetzt, Sie beheben Ihre Tsubscription
Klassendeklaration mit der Methode). Der getfBillingObj()
Code, den Sie zeigte gibt den richtigen Objektzeiger, wie durch den folgenden Code gezeigt:
uses
System.Rtti;
type
TMyObject = class
public
Name: string;
constructor Create(const aName: string);
end;
Tsubscription = class(TMyObject)
private
fBilling: TMyObject;
public
constructor Create(const aName: string);
destructor Destroy; override;
function getfBillingObj(const aRttiProperty: TRttiProperty): TMyObject;
property billing: TMyObject read fBilling;
end;
constructor TMyObject.Create(const aName: string);
begin
inherited Create;
Name := aName;
end;
constructor Tsubscription.Create(const aName: string);
begin
inherited Create(aName);
fBilling := TMyObject.Create('bill');
end;
destructor Tsubscription.Destroy;
begin
fBilling.Free;
end;
function Tsubscription.getfBillingObj(const aRttiProperty: TRttiProperty): TMyObject;
begin
Result := aRttiProperty.GetValue(Self).AsType<TMyObject>;
end;
var
Ctx: TRttiContext;
prop: TRttiProperty;
sub: Tsubscription;
bill: TMyObject;
begin
sub := Tsubscription.Create('sub');
try
prop := ctx.GetType(Tsubscription).GetProperty('billing');
bill := sub.getfBillingObj(prop);
// bill.Name is 'bill' as expected...
finally
sub.Free;
end;
end;
Davon abgesehen, ist es nicht notwendig, RTTI in dieser Situation zu verwenden, da TSubscription
direkte hat Zugang zu seinen eigenen internen Feldern:
function TSubscription.getfBillingObj: TMyObject
begin
Result := fBilling;
end;
Aber auch das ist überflüssig, da die billing
Eigenschaft publi ist c. Jeder Anrufer kann nur verwenden, um die billing
Eigenschaft als Service-Leistung:
var
sub: Tsubscription;
bill: TMyObject;
begin
sub := Tsubscription.Create('sub');
try
bill := sub.billing;
// bill.Name is 'bill' as expected...
finally
sub.Free;
end;
end;
Gut, das nur übertrieben, wenn man nur verwenden kann, 'Ergebnis: = MySubscriptionInstance.Billing;' statt. –
@Remy - Meine Vermutung wäre Loki will auf das Feld schreiben. –
@SertacAkyuz: Wenn er die Speicheradresse des 'fBilling'-Feldes selbst benötigt, ist das Durchlaufen von' TRttiProperty' nicht der richtige Weg (außer man tippt ihn in 'TRttiInstanceProperty' und dekodiert dessen' PropInfo ^. SetProc-Wert). Eine bessere Option wäre, den Offset des Feldes "fBilling" innerhalb der Klasse "Tsubscription" zu erhalten, indem man 'aRttiType.GetField ('fBilling'). Offset '(wobei' aRttiType 'die Klasse' TSubscription 'darstellt) und dann fügen Sie diesen Offset der Startspeicheradresse eines Tsubscription-Objekts hinzu. –