我有一个非常复杂的嵌套记录类型。我需要在方法调用后监视它的字段值的变化。我使用RTTI来做(最初从here复制):
procedure CompareFields(const Rec1, Rec2: Pointer; const RectTypeInfo: TRttiType;
const BaseName: string; const BaseOffset: Integer; const Lines: TStrings);
var
R1Field, R2Field: Pointer;
MyField: TRttiField;
State: string;
Path: string;
begin
if RectTypeInfo.TypeKind = tkRecord then
begin
for MyField in RectTypeInfo.GetFields do
begin
R1Field := Pointer(Integer(Rec1) + BaseOffset + MyField.Offset);
R2Field := Pointer(Integer(Rec2) + BaseOffset + MyField.Offset);
if CompareMem(R1Field, R2Field, MyField.FieldType.TypeSize) then
State := '=='
else
State := '<>';
Path := BaseName + '.' + MyField.Name;
Lines.Add(Format('%2s | %-20s | +%2d | %10s[%2d] | %22s | %22s', [State, Path,
BaseOffset + MyField.Offset,
MyField.FieldType.ToString,
MyField.FieldType.TypeSize,
MyField.GetValue(R1Field).ToString,
MyField.GetValue(R2Field).ToString]));
if MyField.FieldType.TypeKind = tkRecord then
CompareFields(Rec1, Rec2, MyField.FieldType, Path, BaseOffset + MyField.Offset, Lines);
end;
end;
end;
CompareMem
部分工作正常并清楚地表明已更改的字段。但问题在于报告拖曳记录的价值。 MyField.GetValue(R1Field).ToString
有时会返回一个随机值,因为MyField.GetValue(R1Field)
会使用随机值填充结果。
这是一个演示问题的示例:
type
TMyRec1 = record
F11: Integer;
F12: Boolean;
F13: Double;
end;
TMyRec2 = record
F21, F22: TMyRec1;
F23: Integer;
F24: TMyRec1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyContext: TRttiContext;
Rec1, Rec2: TMyRec2;
begin
FillChar(Rec1, SizeOf(Rec1), #0);
FillChar(Rec2, SizeOf(Rec1), #0);
CompareFields(@Rec1, @Rec2, MyContext.GetType(TypeInfo(TMyRec2)), 'TMyRec2', 0,
Memo1.Lines);
end;
结果是:
== | TMyRec2.F21 | + 0 | TMyRec1[16] | (record) | (record)
== | TMyRec2.F21.F11 | + 0 | Integer[ 4] | 0 | 0
== | TMyRec2.F21.F12 | + 4 | Boolean[ 1] | False | False
== | TMyRec2.F21.F13 | + 8 | Double[ 8] | 0 | 0
== | TMyRec2.F22 | +16 | TMyRec1[16] | (record) | (record)
== | TMyRec2.F22.F11 | +16 | Integer[ 4] | 0 | 0
== | TMyRec2.F22.F12 | +20 | Boolean[ 1] | False | False
== | TMyRec2.F22.F13 | +24 | Double[ 8] | 0 | 0
== | TMyRec2.F23 | +32 | Integer[ 4] | 21013568 | 0 <<--
== | TMyRec2.F24 | +40 | TMyRec1[16] | (record) | (record)
== | TMyRec2.F24.F11 | +40 | Integer[ 4] | 0 | 0
== | TMyRec2.F24.F12 | +44 | Boolean[ 1] | False | False
== | TMyRec2.F24.F13 | +48 | Double[ 8] | 9.92338439963001E-303 | 0 <<--
正如您所看到的,TMyRec2.F23
和TMyRec2.F24.F13
似乎的值不是&#39; 0&#39;甚至在致电FillChar
之后!