Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi [Rtti] Generische Attribute (https://www.delphipraxis.net/149666-%5Brtti%5D-generische-attribute.html)

Najo 26. Mär 2010 22:01


[Rtti] Generische Attribute
 
Hallo,

ich versuche gerade ein wenig Erfahrung mit der Rtti zu sammeln und versuche Attribute mit Generics zu verheiraten. In meinen Ansatz scheint aber irgendwie ein Fehler zu stecken:

Delphi-Quellcode:
unit uSettings;

interface

type
  TSettingAttribute<T> = class(TCustomAttribute)
  private
    m_default: T;
  public
    constructor Create(const _default: T);
  end;

  TSettings = class
  private
    procedure SetToDefault();

  public
    [TSettingAttribute<boolean>(false)]
    m_AllowMultipleStarts: boolean;

    constructor Create();
    destructor Destroy(); override;
  end;

implementation

uses
  Rtti;

{ TSettings }

constructor TSettings.Create();
begin
  SetToDefault();
end;

destructor TSettings.Destroy();
begin

  inherited;
end;

procedure TSettings.SetToDefault();
var
  ctx : TRttiContext;
  t  : TRttiType;
  f  : TRttiField;
  a  : TCustomAttribute;
  v  : TValue;
begin
  ctx := TRttiContext.Create();
  try
    t := ctx.GetType(self);

    for f in t.GetFields() do
    begin
      for a in f.GetAttributes() do
      begin
        if a is TSettingAttribute<f.ClassType> then            // Hier Fehler
        begin
          v := f.GetValue(self);
          v := TSettingAttribute<f.ClassType>(a).m_default;    // Und hier
          f.SetValue(self, v);
        end;
      end;
    end;

  finally
    ctx.Free();
  end;
end;

{ TSettingAttribute<T> }

constructor TSettingAttribute<T>.Create(const _default: T);
begin
  m_default := _default;
end;

end.

In der Methode SetToDefault möchte ich alle Variablen, die mit dem generischen Attribute gekennzeichnet sind durchlaufen und mit dem Default Wert belegen. Der Compiler scheint sich allerdings an meinem Konstrukt TSettingAttribute<f.ClassType> zu stören. Wenn ich statt f.ClassType zum Beispiel integer schreibe kann ich es kompelieren.

Kann mir jemand erklären, woran genau sich der Compiler stört bzw. wie ich es richtig machen muss?

Viele Grüße und Danke
Najo

Khabarakh 27. Mär 2010 01:37

Re: [Rtti] Generische Attribute
 
Das kann so nicht funktionieren - von welchem Typ sollte auch
Delphi-Quellcode:
TSettingAttribute<f.ClassType>(a).m_default
sein?
Wenn du nun also in SetToDefault keine Generics benutzen kannst, solltest du sie für das Attribut überhaupt nicht mehr benötigen. Nimm für den Parameter einfach Variant (hoffentlich funktioniert das auch :stupid: ).

Najo 27. Mär 2010 06:56

Re: [Rtti] Generische Attribute
 
Guten Morgen Khabarakh,

vielleicht habe ich auch was falsch verstanden. Ich dachte mit f habe ich meine Variable m_AllowMultipleStarts erwischt und f.ClassType ist dann boolean, so dass
Delphi-Quellcode:
TSettingAttribute<f.ClassType>(a).m_default
ebenfalls vom Typ boolean ist.

Ist das falsch? Ich wollte ungern das Attribute ungenerisch machen, indem ich m_default als Varianten oder String deklariere.

Vielen Dank für die Hilfe
Najo

Khabarakh 27. Mär 2010 12:59

Re: [Rtti] Generische Attribute
 
Zitat:

Zitat von Najo
so dass [...] ebenfalls vom Typ boolean ist.

Zur Laufzeit wäre es das, ja, aber Delphi ist immer noch eine statisch typisierte Sprache (dynamisch typisierte brauchen sowieso keine Generics ;) ). Noch einmal: Wenn du TSettingAttribute<f.ClassType>(a).m_default in eine Variable x speichern wolltest, wie würdest du x deklarieren? Der Compiler ist da genauso ratlos wie du. Zu Recht.

Zitat:

Zitat von Najo
Ich wollte ungern das Attribute ungenerisch machen, indem ich m_default als Varianten oder String deklariere.

Aber warum nicht? Für den Benutzer deines Attributs macht das jedenfalls keinen Unterschied.

Generell kann man wohl behaupten: Generics und Reflection schließen sich in den allermeisten Fällen gegenseitig aus.

Najo 27. Mär 2010 21:29

Re: [Rtti] Generische Attribute
 
Hallo Khabarakh,

hatte ich nicht bedacht, dass die Generics statisch ausgewertet werden. Dann ist der Fehler für mich auch nachvollziehbar.

Viele Grüße und danke!
Najo


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:29 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