gpt4 book ai didi

delphi - 深度对象比较 Delphi

转载 作者:行者123 更新时间:2023-12-03 14:37:01 25 4
gpt4 key购买 nike

在 Delphi 中寻找一种方法来为我进行深度对象比较,最好是基于 2010 RTTI,因为我的对象不是从 TComponent 继承的。我正在 DUnit 中开发一个测试框架,需要一些可靠的东西来准确指出哪个字段导致了问题(序列化比较让它有点模糊)。

最佳答案

我自己解决了这个问题,作为 TObject 的类帮助器实现,因此如果人们需要的话可以在任何地方使用。 D2010 及更高版本由于 RTTI,但您也许可以将其转换为使用原始 RTTI 内容。

下面的代码可能有错误,因为最初我的代码是针对 DUnit 的,并且在其中进行了大量检查而不是更改结果,并且不支持 TCollections 或大量其他特殊情况,但可以通过使用 if- 进行调整elseif-then 在中间切换。

如果您有任何建议和补充,请随时发表评论,以便我可以将它们添加到其中,以便其他人可以使用它。

祝你编码愉快

巴里

unit TObjectHelpers;

interface
uses classes, rtti;

type

TObjectHelpers = class Helper for TObject
function DeepEquals (const aObject : TObject) : boolean;
end;

implementation

uses sysutils, typinfo;

{ TObjectHelpers }

function TObjectHelpers.DeepEquals(const aObject: TObject): boolean;
var
c : TRttiContext;
t : TRttiType;
p : TRttiProperty;
begin

result := true;

if self = aObject then
exit; // Equal as same pointer

if (self = nil) and (aObject = nil) then
exit; // equal as both non instanced

if (self = nil) and (aObject <> nil) then
begin
result := false;
exit; // one nil other non nil fail
end;

if (self <> nil) and (aObject = nil) then
begin
result := false;
exit; // one nil other non nil fail
end;

if self.ClassType <> aObject.ClassType then
begin
result := false;
exit;
end;

c := TRttiContext.Create;
try
t := c.GetType(aObject.ClassType);

for p in t.GetProperties do
begin

if ((p.GetValue(self).IsObject)) then
begin

if not TObject(p.GetValue(self).AsObject).DeepEquals(TObject(p.GetValue(aObject).AsObject)) then
begin
result := false;
exit;
end;

end
else if AnsiSameText(p.PropertyType.Name, 'DateTime') or AnsiSameText(p.PropertyType.Name, 'TDateTime') then
begin

if p.GetValue(self).AsExtended <> p.GetValue(aObject).AsExtended then
begin
result := false;
exit;
end;

end
else if AnsiSameText(p.PropertyType.Name, 'Boolean') then
begin

if p.GetValue(self).AsBoolean <> p.GetValue(aObject).AsBoolean then
begin
result := false;
exit;
end;

end
else if AnsiSameText(p.PropertyType.Name, 'Currency') then
begin

if p.GetValue(self).AsExtended <> p.GetValue(aObject).AsExtended then
begin
result := false;
exit;
end;

end
else if p.PropertyType.TypeKind = tkInteger then
begin

if p.GetValue(self).AsInteger <> p.GetValue(aObject).AsInteger then
begin
result := false;
exit;
end;

end
else if p.PropertyType.TypeKind = tkInt64 then
begin

if p.GetValue(self).AsInt64 <> p.GetValue(aObject).AsInt64 then
begin
result := false;
exit;
end;

end
else if p.PropertyType.TypeKind = tkEnumeration then
begin

if p.GetValue(self).AsOrdinal <> p.GetValue(aObject).AsOrdinal then
begin
result := false;
exit;
end;

end
else
begin

if p.GetValue(self).AsVariant <> p.GetValue(aObject).AsVariant then
begin
result := false;
exit;
end;

end;

end;

finally
c.Free;
end;

end;

end.

关于delphi - 深度对象比较 Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7994266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com