RTTI:如何获取字段的对象指针?
RTTI: how to get the object pointer of a field?
我有一个名为 aRttiProperty
的 TRttiProperty
变量,它指向下面的 属性:
Tsubscription = class(TMyObject)
private
fBilling: TMyObject;
public
property billing: TMyObject read fBilling; // << aRttiProperty point to this member
end;
现在,如何从 aRttiProperty
中提取 fBilling
对象指针?
我尝试这样做,但它不起作用:
function Tsubscription.getfBillingObj(const aRttiProperty: TRttiProperty): TMyObject
begin
Result := aRttiProperty.GetValue(Self).AsType<TMyObject>;
end;
它返回父 TSubscription
对象而不是 fbilling
字段对象。
您在问题中显示的代码非常好(前提是您修改了 Tsubscription
class 声明以包含 getfBillingObj()
方法)。您显示 returns 正确对象指针的 getfBillingObj()
代码,如以下代码所示:
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;
也就是说,在这种情况下没有必要使用 RTTI,因为 TSubscription
可以直接访问它自己的内部字段:
function TSubscription.getfBillingObj: TMyObject
begin
Result := fBilling;
end;
但即使这样也是多余的,因为 billing
属性 是 public。任何调用者都可以按原样使用 billing
属性:
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;
我有一个名为 aRttiProperty
的 TRttiProperty
变量,它指向下面的 属性:
Tsubscription = class(TMyObject)
private
fBilling: TMyObject;
public
property billing: TMyObject read fBilling; // << aRttiProperty point to this member
end;
现在,如何从 aRttiProperty
中提取 fBilling
对象指针?
我尝试这样做,但它不起作用:
function Tsubscription.getfBillingObj(const aRttiProperty: TRttiProperty): TMyObject
begin
Result := aRttiProperty.GetValue(Self).AsType<TMyObject>;
end;
它返回父 TSubscription
对象而不是 fbilling
字段对象。
您在问题中显示的代码非常好(前提是您修改了 Tsubscription
class 声明以包含 getfBillingObj()
方法)。您显示 returns 正确对象指针的 getfBillingObj()
代码,如以下代码所示:
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;
也就是说,在这种情况下没有必要使用 RTTI,因为 TSubscription
可以直接访问它自己的内部字段:
function TSubscription.getfBillingObj: TMyObject
begin
Result := fBilling;
end;
但即使这样也是多余的,因为 billing
属性 是 public。任何调用者都可以按原样使用 billing
属性:
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;