加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何使用TypInfo单元获取’record’类型的属性

发布时间:2020-12-15 04:34:20 所属栏目:大数据 来源:网络整理
导读:我有这种记录类型 TDoublePoint = record X : Double; Y : Double; end; 然后我有这个属性的对象 uses ..TypInfo;TCell = class(TPersistent) private FZoom : TDoublePoint published property Zoom : TDoublePoint read FZoom write FZoom;end; 但是当我想
我有这种记录类型
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在函数中是nil.

但为什么?
在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记录类型中.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读