Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi D2010 RTTI besitzt ein object scope ? (https://www.delphipraxis.net/152094-d2010-rtti-besitzt-ein-object-scope.html)

skydiablo 10. Jun 2010 20:59

Delphi-Version: 2010

D2010 RTTI besitzt ein object scope ?
 
hi @ all...

ich bin derzeit am rumschrauben mit delphi 2010 und den neuen RTTI "klassen" (in anfürungszeichen, da mir das mit pseudo record als object getarnt bekannt ist)... nun meine eigentlich frage:

ich hab mir hier mal eine function gebaut die mir ein bestimmtes attribut auslesen soll:

Delphi-Quellcode:
function getAttribute(ctx : TRttiContext; obj : TObject; attributeClass : TClass) : TBasicAttribute;
var
//  ctx: TRttiContext;
  t : TRttiType;
  p : TRttiProperty;
  a : TCustomAttribute;
begin
  result := nil;
//  ctx := TRttiContext.Create;
  try
    t := ctx.GetType(obj.ClassType);
    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
//    ctx.Free;
  end;
end;
in dieser schon etwas angepassten variante übergebe ich ein bereits bestehendes TRttiContext "object" mit. diese function gibt mir nun also ein TBasicAttribute bzw davon abgeleitetes attribut zurück. dieses object hat eine property, setze ich da nun ein value und rufe dann die function "getAttribute" wieder auf, hat das gleiche attribut vom gleichen object wieder den default wert ? gibt es denn keine möglichkeit attributen einen wert nachträglich zu setzen und dieses veränderten wert nachträglich wieder ab zu fragen ? es ist mir auch bewusst, dass hier die attribute auf die klasse bezieht und nicht auf das object selst, aber gibt es eine möglichkeit atribute an objecte zu binden ?

hoffe meine ausführung ist ansatzweise nachvollziehbar ? würde mich über eine antwort freuen...

greez & thx, sky...

s.h.a.r.k 10. Jun 2010 21:07

AW: D2010 RTTI besitzt ein object scope ?
 
Attribute sind nur an eine Klasse gebunden, nicht an ein Objekt.

Und nein, soweit ich weiß, kannst du zur Lautzeit nicht an den Attributen herumschrauben.

skydiablo 10. Jun 2010 21:37

AW: D2010 RTTI besitzt ein object scope ?
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1027975)
soweit ich weiß, kannst du zur Lautzeit nicht an den Attributen herumschrauben.

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...

greez & thx, sky...

Stevie 11. Jun 2010 07:06

AW: D2010 RTTI besitzt ein object scope ?
 
Zitat:

Zitat von skydiablo (Beitrag 1027977)
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:38 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz