我有这张唱片
TDoublePoint = record
X : Double;
Y : Double;
end;
那么我就有了这个属性的对象
uses ..TypInfo;
TCell = class(TPersistent)
private
FZoom : TDoublePoint
published
property Zoom : TDoublePoint read FZoom write FZoom;
end;
但是,当我想用这个函数获得这个属性的PropInfo时:
function GetKind(AObject:TObject; Propertyname :shortstring):TTypeKind;
var p :ppropinfo;
begin
p:=GetPropInfo(AObject, Propertyname); // <p = nil
Result:= p^.proptype^.Kind;
end;
。。。。
c := TCell.Create;
GetKind(c, 'Zoom'); // <- error
c.Free;
我得到了错误,因为变量p是函数中的零。
但是为什么呢?在tkRecord
中有TTypeKind,所以我希望在读取/写入记录类型的属性时没有问题,但似乎不可能(?)谷歌搜索并没有提供太多信息。
发布于 2017-08-10 13:55:25
默认情况下,Delphi7不会为记录类型生成RTTI,因此使用记录类型的published
属性也不会有RTTI (您可以使用TypInfo.GetPropList()
来确认这一点)。
在某种程度上,这是一个记录在案的限制:
发布的属性仅限于某些数据类型。可以发布序号、字符串、类、接口、变体和方法指针类型.
然而,有一个解决办法。如果记录类型包含任何编译器管理的数据类型(长字符串、接口、动态数组等),那么将为该记录类型生成RTTI,以及使用该记录类型的任何published
属性,因此GetPropInfo()
可以找到这些属性(我已经确认这在Delphi 7中确实有效)。
您的TDoublePoint
记录不包含任何编译器管理的数据类型,因此GetPropInfo()
将为您的TCell.Zoom
属性返回零。
RTTI问题在以后的版本中得到了修正(不确定是哪个版本)。我猜可能是在Delphi2010,当扩展RTTI首次被引入的时候)。例如,您所显示的代码在XE中为我工作。GetPropInfo()
可以按照预期找到Zoom
属性,而不必在TDoublePoint
记录类型中引入任何编译器托管类型。
https://stackoverflow.com/questions/45623737
复制