如何使用 TypInfo 单元获取 'record' 类型的 属性
How to get property of the 'record' type using TypInfo unit
我有这个记录类型
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
,所以我预计记录类型的read/write和属性没有问题,但似乎不可能(?)
Google 搜索结果不多。
Delphi 7 默认不为记录类型生成 RTTI,因此使用记录类型的 published
属性 也不会有 RTTI(您可以使用TypInfo.GetPropList()
确认)。
在某一时刻,这是记录在案的限制:
Published properties are restricted to certain data types. Ordinal, string, class, interface, variant, and method-pointer types can be published.
但是,有一个解决方法。 如果 记录类型包含任何编译器管理的数据类型(长字符串、接口、动态数组等),那么将为该记录类型生成 RTTI,任何 published
属性 使用该记录类型,因此 GetPropInfo()
可以找到此类属性(我已经确认这在 Delphi 7 中有效)。
您的 TDoublePoint
记录不包含任何编译器管理的数据类型,所以这就是 GetPropInfo()
为您的 TCell.Zoom
属性.[=21 返回 nil 的原因=]
该 RTTI 问题已在更高版本中修复(不确定是哪个版本。我猜可能是在 Delphi 2010 年首次引入扩展 RTTI 时)。例如,您展示的代码在 XE 中对我有效。 GetPropInfo()
可以按预期找到 Zoom
属性,而无需将任何编译器管理的类型引入 TDoublePoint
记录类型。
我有这个记录类型
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
,所以我预计记录类型的read/write和属性没有问题,但似乎不可能(?)
Google 搜索结果不多。
Delphi 7 默认不为记录类型生成 RTTI,因此使用记录类型的 published
属性 也不会有 RTTI(您可以使用TypInfo.GetPropList()
确认)。
在某一时刻,这是记录在案的限制:
Published properties are restricted to certain data types. Ordinal, string, class, interface, variant, and method-pointer types can be published.
但是,有一个解决方法。 如果 记录类型包含任何编译器管理的数据类型(长字符串、接口、动态数组等),那么将为该记录类型生成 RTTI,任何 published
属性 使用该记录类型,因此 GetPropInfo()
可以找到此类属性(我已经确认这在 Delphi 7 中有效)。
您的 TDoublePoint
记录不包含任何编译器管理的数据类型,所以这就是 GetPropInfo()
为您的 TCell.Zoom
属性.[=21 返回 nil 的原因=]
该 RTTI 问题已在更高版本中修复(不确定是哪个版本。我猜可能是在 Delphi 2010 年首次引入扩展 RTTI 时)。例如,您展示的代码在 XE 中对我有效。 GetPropInfo()
可以按预期找到 Zoom
属性,而无需将任何编译器管理的类型引入 TDoublePoint
记录类型。