'Delphi - recursively checking class properties attributes
I have tree of class to hold some program parameters. Sometimes there is one level, but sometimes the may child objects, or even children lists with objects etc ... I would like to check / apply some changes to properties using attributes. It's easy at the first level through rtti. I'm struggling to do so recursively : how can I retrieve children instances to apply the check procedure ?
Sort of:
procedure check(poInstance : TConfClass) ;
var
c : TRTTIContext;
f : TRTTIField;
p : TRTTIProperty;
t: TRTTIType;
a : TCustomAttribute;
begin
c := TRTTIContext.Create;
for p in c.GetType(poValue.ClassType).GetProperties do
begin
if p.PropertyType.TypeKind = tkClass then
begin
if Copy(p.PropertyType.ToString,1,5) = 'TList' then
begin
// loop over the list and if it's an instance of TConfClass then call check with this instance
end
else
// if it's an instance of TConfclass then call Check(instance)>
end
else begin
for a in p.GetAttributes do begin
// check / alter values following attributes
end;
end ;
end;
end;
c.Free;
end;
What is the best way to achieve this ?
Solution 1:[1]
I could find a solution
procedure BeforeSerializeClass(poValue: TObject);
var
loContext : TRTTIContext;
loProp : TRTTIProperty;
loType : TRTTIType;
loAttr : TCustomAttribute;
loMeth : TRTTIMethod;
loValue : TValue;
nCnt : integer;
loTmp : TObject;
begin
loContext := TRTTIContext.Create;
for loProp in loContext.GetType(poValue.ClassType).GetProperties do
begin
if loProp.PropertyType.TypeKind = tkClass then
begin
loTmp := loProp.GetValue(poValue).AsObject ;
loType := loCOntext.GetType(loTmp.ClassInfo);
loMeth := loType.GetMethod('ToArray');
if Assigned(loMeth) then begin
loValue := loMeth.Invoke(loTmp, []);
Assert(loValue.IsArray);
nCnt := loValue.GetArrayLength;
while nCnt > 0 do begin
Dec(nCnt);
BeforeSerializeClass(loValue.GetArrayElement(ncnt).AsObject);
end;
end
else begin
BeforeSerializeClass(loProp.GetValue(poValue).AsObject) ;
end;
end
else begin
for loAttr in loProp.GetAttributes do begin
if loAttr is TCrypt then begin
(loAttr as TCrypt).Value := loProp.GetValue(poValue).AsString;
loProp.SetValue(poValue,(loAttr as TCrypt).encrypt);
end;
end ;
end;
end;
loContext.Free;
end;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | halted |
