我有这种记录类型
TDoublePoint = record X : Double; Y : Double; end;
然后我有这个属性的对象
uses ..TypInfo; TCell = class(TPersistent) private FZoom : TDoublePoint published property Zoom : TDoublePoint read FZoom write FZoom; end;
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;
但为什么?
在TTypeKind中有tkRecord,所以我预计读/写记录类型的属性没有问题,但看起来,它是不可能的(?)
谷歌搜索并没有说太多.
解决方法
默认情况下,Delphi 7不会为记录类型生成RTTI,因此使用记录类型的已发布属性也不会具有RTTI(您可以使用TypInfo.GetPropList()来确认).
有一次,这是一个记录在案的限制:
Published properties are restricted to certain data types. Ordinal,string,class,interface,variant,and method-pointer types can be published.
但是,有一种解决方法.如果记录类型包含任何编译器管理的数据类型(长字符串,接口,动态数组等),则将为该记录类型生成RTTI,使用该记录类型的任何已发布属性也将生成,因此GetPropInfo()可以找到这样的属性(我已经确认这在Delphi 7中有效).
您的TDoublePoint记录不包含任何编译器管理的数据类型,因此GetPropInfo()为您的TCell.Zoom属性返回nil.
RTTI问题在更高版本中得到修复(不确定哪一个.我猜测可能在Delphi 2010中,当扩展RTTI首次推出时).例如,您显示的代码在XE中按原样运行. GetPropInfo()可以按预期找到Zoom属性,而不必将任何编译器管理的类型引入到TDoublePoint记录类型中.