also man kann durchaus attribute wie ganz normale klassen/objecte benutzen... zB könnte man ein validator so hinterlegen. aber egal, nicht das thema hier. das einzige was ich nun in der richtung gefunden habe ist, wenn man vielleicht das "TRttiType" object und die eigentliche klasse/object mit einander verknüpft, und bei weiteren
RTTI abfragen immer dieses "TRttiType" object nutzen würde, so bleiben die änderungen in den propertys der attribute erhalten... ob das nun im sinne des erfinders ist, wäre jetzt noch fraglich...
Dein Problem ist, dass du bei jedem Aufruf von getAttribute ein neues TRttiType Objekt erstellst, bei welchem auch wieder die Attribute Objekte erstellt werden. Würdest du hierbei eine Art Cache aufbauen, wo du alle jemals abgefragten TRttiType Objekte vorhälst und zuerst dort nachschaust, dann würden auch deine Attribute Objekte am leben bleiben.
Außerdem eine Warnung, was die Benutzung von TRttiContext mit Caching von
Rtti-Objekten angeht. Benutz dafür eine globale Variable und gib ihn nicht als Parameter in Funktionen, ansonsten fliegt dir nämlich das Ding um die Ohren.
Delphi-Quellcode:
var
TypeCache: TList<TRttiType>;
ctx: TRttiContext;
function getAttribute(obj: TObject; attributeClass: TClass): TBasicAttribute;
var
t: TRttiType;
p: TRttiProperty;
a: TCustomAttribute;
begin
result := nil;
try
t := nil;
for t in TypeCache do
begin
if t.ClassName = obj.ClassName then
begin
Break;
end;
end;
if not Assigned(t) then
begin
t := ctx.GetType(obj.ClassType);
TypeCache.Add(t);
end;
for p in t.GetProperties do
for a in p.GetAttributes do
if a is attributeClass then
begin
result := a as TBasicAttribute;
exit;
end;
finally
end;
end;
...
initialization
if not Assigned(TypeCache) then
begin
TypeCache := TList<TRttiType>.Create;
end;
finalization
if Assigned(TypeCache) then
begin
TypeCache.Free;
end;
end.