寻找一个delphi库或代码片段,将对我进行深层对象比较,最好是2010 RTTI,因为我的对象不会从TComponent继承.有谁知道在哪里可以找到一个,我正在DUnit开发一个测试框架,需要一些坚实的东西,它将指出哪个领域引起问题(序列化比较使它有点模糊).
干杯,
巴里
解决方法
排序解决这个我自己,实现为一个类助手TObject所以可以使用到任何地方,如果人们想要它. D2010由于RTTI,但您可能可以将其转换为使用原始RTTI的东西.
下面的代码可能是错误的,因为我原来是DUnit,并且有很多检查,而不是改变结果,不支持TCollections或其他特殊情况的负载,但可以通过使用if-elseif然后修改在中间切换
如果您有任何建议和补充,请随时给予评论,以便我们添加它们,以便其他人可以使用它.
有乐趣的编码
巴里
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.