我有这种记录类型
TDoublePoint = record
X : Double;
Y : Double;
end;
Run Code Online (Sandbox Code Playgroud)
然后我有这个属性的对象
uses ..TypInfo;
TCell = class(TPersistent)
private
FZoom : TDoublePoint
published
property Zoom : TDoublePoint read FZoom write FZoom;
end;
Run Code Online (Sandbox Code Playgroud)
但是当我想用这个函数得到这个属性的PropInfo时:
function GetKind(AObject:TObject; Propertyname :shortstring):TTypeKind;
var p :ppropinfo;
begin
p:=GetPropInfo(AObject, Propertyname); // <p = nil
Result:= p^.proptype^.Kind;
end;
Run Code Online (Sandbox Code Playgroud)
.. ..
c := TCell.Create;
GetKind(c, 'Zoom'); // <- error
c.Free;
Run Code Online (Sandbox Code Playgroud)
我得到错误,因为变量p在函数中是nil.
但为什么?有tkRecord在TTypeKind,所以我希望没有问题,读/写记录类型的属性,但现在看来,这是不可能的(?)谷歌搜索没有告诉太多.
Rem*_*eau 10
默认情况下,Delphi 7不会为记录类型生成RTTI,因此published使用记录类型的属性也不会具有RTTI(您可以使用它TypInfo.GetPropList()来确认).
有一次,这是一个记录在案的限制:
已发布的属性仅限于某些数据类型.可以发布序数,字符串,类,接口,变体和方法指针类型.
但是,有一种解决方法. 如果记录类型包含任何编译器管理的数据类型(长字符串,接口,动态数组等),则将为该记录类型生成RTTI published,使用该记录类型的任何属性也将生成,因此GetPropInfo()可以找到此类属性(我已经确认这在Delphi 7中有效.
您的TDoublePoint记录不包含任何编译器管理的数据类型,因此这就是GetPropInfo()为您的TCell.Zoom属性返回nil的原因.
RTTI问题在更高版本中得到修复(不确定哪一个.我猜测可能在Delphi 2010中,当扩展RTTI首次推出时).例如,您显示的代码在XE中按原样运行. GetPropInfo()可以Zoom按预期找到属性,而不必将任何编译器管理的类型引入TDoublePoint记录类型.
| 归档时间: |
|
| 查看次数: |
490 次 |
| 最近记录: |