Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wozu sind Attribute gut ? (https://www.delphipraxis.net/175701-wozu-sind-attribute-gut.html)

Der schöne Günther 6. Aug 2013 12:52

AW: Wozu sind Attribute gut ?
 
Nachdem ich mir Attribute nun auch etwas näher angesehen habe, stört mich eins doch irgendwie gewaltig: Vielleicht habe ich nicht lange genug im Wasser der AOP gebadet, aber spontan weiß ich nur einen Weg, an die Attribute zu kommen:

Mittels RTTI über
Delphi-Quellcode:
GetAttributes(): TArray<TCustomAttribute>
auf einem
Delphi-Quellcode:
TRttiObject
. Nehmen wir an, ich habe eine ganz normale Property
Delphi-Quellcode:
Derp
eines Objekts und möchte nun schauen, ob ein Attribut "Lebensmittel" für diese Property existiert bzw. ob dieses Attribut sagt "Wurst" oder "Käse". Jetzt muss ich über alle Properties meines Objekts iterieren, bis ich eine finde, welche den Namen 'Derp' hat. Nachdem ich die Property nun habe, kann ich wiederum alle Attribute durchsuchen, nach Namen suchen und weitermachen.

Das Durch-Iterieren stört mich nicht. Aber dass ich nicht Dinge tun kann wie
Delphi-Quellcode:
meinObjekt.Derp.GetAttributes()
sondern doch hier eigentlich aufgrund der RTTI gezwungen bin, mit Zeichenfolgen zu arbeiten, oder? Soll bedeuten, ich muss in meinem Quelltext mindestens einen String mit dem Inhalt 'Derp' und 'Lebensmittel' ablegen. Ändere ich nun den Namen der Property und/oder des Attributs, habe ich ein Problem: Die Strings passen nicht mehr. Denn ich kenne keinen Weg, einer Methode eine "Property an sich" übergeben zu können. Attribute schon, das sind ja normale Klassen. Aber bei Properties scheitert es hier irgendwie...

jaenicke 6. Aug 2013 13:55

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1223694)
Soll bedeuten, ich muss in meinem Quelltext mindestens einen String mit dem Inhalt 'Derp' und 'Lebensmittel' ablegen.

Das verstehe ich gerade nicht... wofür willst du das denn benutzen?
Mal ein Beispiel:
Delphi-Quellcode:
type
  ColorElementAttribute = class(TCustomAttribute)
  private
    var
      FColor: TColor;
    procedure SetColor(const Value: TColor);
  public
    constructor Create(const AColor: TColor);
    property Color: TColor read FColor write SetColor;
  end;

constructor ColorElementAttribute.Create(const AColor: TColor);
begin
  FColor := AColor;
end;

procedure ColorElementAttribute.SetColor(const Value: TColor);
begin
  FColor := Value;
end;
Und im Formular mit zwei Buttons und zwei Memos:
Delphi-Quellcode:
  TFormX = class(TForm)
    Button1: TButton;
    Button2: TButton;
    [ColorElement(clRed)]
    Memo1: TMemo;
    [ColorElement(clBlue)]
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
  end;

procedure TFormX.Button1Click(Sender: TObject);
var
  LCtx: TRttiContext;
  LField: TRttiField;
  LAttr: TCustomAttribute;
begin
  for LField in LCtx.GetType(Self.ClassInfo).GetDeclaredFields do
    for LAttr in LField.GetAttributes do
      if LAttr is ColorElementAttribute then
        SetPropValue(LField.GetValue(Self).AsObject, 'Color', ColorElementAttribute(LAttr).Color);
end;
Wenn ich den Namen des Attributes ändere, kompiliert das nicht mehr. Und in deinem Fall könnte das z.B. eine Enumeration sein, dann brauche ich auch da keinen String, das könnte dann auch beim Kompilieren geprüft werden.

Der schöne Günther 6. Aug 2013 14:29

AW: Wozu sind Attribute gut ?
 
Das blöde ist nur, dass in

Delphi-Quellcode:
SetPropValue(LField.GetValue(Self).AsObject, 'Color', ColorElementAttribute(LAttr).Color);
der Name der Property noch einmal redundant als String hinterlegt ist. Möchte ich den Namen der Property ändern, wäre ich so faul, das direkt mittels Refactoring-Funktionen zu erledigen. Das ändert direkt überall den Namen, wo die Property verwendet wird. Der String bleibt dabei natürlich unangetastet. Und fortan finde ich unter diesem Namen keine Property mehr.

Auch die "alte RTTI" bietet nur das Finden über den Namen als String an. In anderen Sprachen habe ich auch nie wirklich etwas mit Reflection gemacht, ist das dort auch so?

Mich bringt das um ehrlich zu sein ziemlich aus dem Konzept.


Das mit der Enumeration ist ein interessanter Weg, das lasse ich mir mal durch den Kopf gehen :-)

Elvis 6. Aug 2013 15:03

AW: Wozu sind Attribute gut ?
 
In C# macht man so etwas mit Expression trees, da sie refactoring-safe sind.

Eine naive Implementierung frei Schnauze:

Code:
public static string GetName<TResult>(Expression<Func<TResult>> expression)
{
   var me = expression.Body as MemeberExpressin;
   if(me != null)
     return me.Member.Name;

   var mce = expression.Body as MetodCallExpressin;
   if(mce != null)
     return mce.Method.Name;
   

   throw ....
}

var methodName = Xyz.GetName(() => "".Substring(0, 1)); // ergibt "Substring"
Auf die Art kann man sich auch direkt PropertyInfos oder MethodInfos (vor allem den korrekten Overload) geben lassen. Sollte man aber möglichst so machen, dass es nicht unnötig oft passiert. Type-safe ist nett, aber schnell ist auch wichtig. ;-)

jaenicke 6. Aug 2013 19:30

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1223718)
Auch die "alte RTTI" bietet nur das Finden über den Namen als String an. In anderen Sprachen habe ich auch nie wirklich etwas mit Reflection gemacht, ist das dort auch so?

Worüber willst du sie denn sonst ansprechen? Property-Referenzen kennt der Compiler nicht. Theoretisch kann man sich dafür etwas basteln... z.B. auch über Attribute. Indem man in einem Attribut hinterlegt, dass es sich dabei um die Farbe handelt. Dann kann man die Property suchen, die die Farbe repräsentiert. Für sinnvoll halte ich das allerdings weniger.

Union 6. Aug 2013 19:32

AW: Wozu sind Attribute gut ?
 
Man könnte sich ja einen Class Helper basteln der die Typeinfo für das die Farbe darstellende Element zurückgibt :twisted:

Der schöne Günther 7. Aug 2013 07:14

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von jaenicke (Beitrag 1223756)
Property-Referenzen kennt der Compiler nicht.

Eben, mir fällt auch absolut nichts ein, wie man dem Compiler etwas von "der Property an sich" erzählen könnte, indem man nur sie selbst anfasst, und nicht noch ihren Namen in einem String aufschreiben muss.

Aber daran haben ja jetzt weniger die Attribute, sondern der Compiler an sich "Schuld". Vielleicht ändert sich das eines Tages ja mal. Die Class Helper und Dinge wie "42.toString()" sagen mir irgendwie, dass Hoffnung besteht :wink:

Stevie 7. Aug 2013 07:43

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Elvis (Beitrag 1223729)
Auf die Art kann man sich auch direkt PropertyInfos oder MethodInfos (vor allem den korrekten Overload) geben lassen. Sollte man aber möglichst so machen, dass es nicht unnötig oft passiert. Type-safe ist nett, aber schnell ist auch wichtig. ;-)

Ein
Code:
var name = typeof(Foo).GetProperty("Bar").Name;
ist nicht schneller als über die Expression.


Zitat:

Zitat von Der schöne Günther (Beitrag 1223777)
Aber daran haben ja jetzt weniger die Attribute, sondern der Compiler an sich "Schuld". Vielleicht ändert sich das eines Tages ja mal. Die Class Helper und Dinge wie "42.toString()" sagen mir irgendwie, dass Hoffnung besteht :wink:

Nicht wirklich, denn die Implementierung dahinter ist eher schmuddelig. Ich wünsche mir ja schon lange property references oder besser noch member references.
Aber dazu müsste einiges am Compiler aufgebohrt werden - was aber nicht zuletzt einiges der arg hässlichen Implementierung der LiveBindings (jupp, die gehen komplett über magic string basierte RTTI) unnötig machen würde.

Elvis 8. Aug 2013 21:35

AW: Wozu sind Attribute gut ?
 
Zitat:

Zitat von Stevie (Beitrag 1223789)
Ein
Code:
var name = typeof(Foo).GetProperty("Bar").Name;
ist nicht schneller als über die Expression.

Jump, ist genau so lahm. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:55 Uhr.
Seite 5 von 5   « Erste     345   

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