property default

Rund um die LCL und andere Komponenten
Antworten
siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

property default

Beitrag von siro »

Hallo zusammen,
ich hab zum Testen mal eine Minimalkomponente geschrieben und da taucht eine Frage auf.

Es gibt den Contruktor zum initialisieren, ich kann aber auch bei published property (das sind ja die Variablen welche im Objektinspektor sichtbar sind) eine default Wert angeben.

Ich hab den Wert mal hier im Code auf 23 gesetzt um es zu verdeutlichen.
Wann wird jetzt welcher Wert gesetzt ? oder anders ausgedrückt welche Initilialisierung ist sinnvoller ? oder in welcher Reihenfolge wird der Code ausgeführt ?

Code: Alles auswählen

TMyObject = class(TComponent)
  private
    fvalue    : Integer;
    procedure SetValue(newValue:Integer);
    function  GetValue:integer;
  protected
 
  public
    constructor create(AOwner:TComponent); override;
    destructor  destroy;                   override;
 
  published
    property value : integer read fvalue write SetValue default 23{ erste Möglichkeit }
end;
 
constructor TMyObject.create(AOwner:TComponent);
begin
  inherited;
  fvalue:=23;    { zweite Möglichkeit }
end;
 
procedure TMyObject.SetValue(newValue:Integer);
begin
  fvalue:=newValue;
end;
 
function TMyObject.GetValue:Integer;
begin
  result:=fvalue;
end;                   
 
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: property default

Beitrag von mse »

Die "erste Möglichkeit" teilt dem streaming-System mit, dass die Property Value nicht in die Formulardatei geschrieben werden muss, wenn der Wert 23 beträgt. Der Wert wird aber nicht verändert. Darum ist auch "zweite Möglichkeit" notwendig.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: property default

Beitrag von wp_xyz »

Die default-Angabe hinter "Property" sagt nur aus, dass der Wert nicht in der lfm-Datei gespeichert wird, wenn er dem hier angegebenen Wert entspricht. Damit ist aber nicht automatisch verbunden, dass der Parameter mit dem Default-Wert initialisiert wird. Du musst also zusätzlich im Constructor noch den Wert setzen, genauso wie von dir gezeigt. Das was du als "erste" und "zweite Möglichkeit" bezeichnest, muss also immer gemeinsam erfolgen.

Würdest du die Zuweisung im Constructor weglassen und du hättest im Objektinspector 23 eingetragen, wäre FValue nach dem Laden der Komponente 0, weil der Default-Wert ja nicht in der lfm-Datei steht. Hättest du im Objektinspektor 24 geschrieben, wäre alles ok.

Würdest du die Default-Angabe bei "Property" weglassen (aber im Contructor den Wert 23 zugewiesen haben), würde immer der richtige Wert verwendet werden. Nachteil ist aber, dass die lfm-Datei unnötig vergrößert wird, und du dir vor allem während der Entwicklung der Komponente das Leben unnötig schwer machst, wenn nämlich einmal eingeführte Properties wieder entfernt werden müssen, weil man sich beim Design in the Ecke manövriert hat - dann hast du bei einer "nicht-default" Property immer einen Formular-Lesefehler, weil die Property nicht mehr bekannt ist; war die entfernte Property aber als "default" deklariert und der Wert war unverändert, kommst du mit einem blauen Auge davon, weil sie ja gar nicht in der lfm-Datei steht.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: property default

Beitrag von siro »

Ui, das ging ja flott hier, erst einmal vielen Dank euch Beiden.

Das fällt mir noch etwas schwer wozu das gut sein soll.....

a) Der Wert muss nicht in die Formulardatei geschrieben werden, wenn ich ihn im Objektinspektor auf 23 stelle,
jedoch schon, wenn ich ihn auf 24 oder 22 oder xxx stelle.
Damit erkläre ich quasi eine Ausnahmesituation um ein paar Bytes zu sparen ?

b) der Wert wäre Null wenn ich ihn im Constructor NICHT initialisiere,
obwohl default auf 23 steht ? Hab ich das so richtig verstanden ?

Wenn ich den Default auf 0 setze zwinge ich ihn dazu den Wert generell ins die Formulardatei zu schreiben ?

Dann ist der Defaultwert eigentlich nur eine Ausnahmesituation wo er ein paar Bytes sparen kann
Wofür braucht man denn so etwas ?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: property default

Beitrag von wp_xyz »

Stell dir vor, die lfm-Datei wird eingelesen. Wenn die Leseroutine die Property findet, wird der Wert aus der lfm-Datei genommen. Wenn nicht, bleibt der Wert unverändert, also so wie ihn der Constructor vorbesetzt hat.

Ein paar Byte können schnell viel werden, wenn sie wiederholt werden. Nimm ein StringGrid mit 100000 Zeilen: wenn man sich hier die Angabe über die Höhe jeder Zeile sparen kann, kommt gleich einiges zusammen. Hauptgrund dürfte aber das Laufzeitverhalten sein, weil die nicht vorhandenen Zeilen auch nicht durch den Parser laufen müssen (lfm-Dateien sind ja Text-Dateien).

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: property default

Beitrag von mse »

Ergänzung zu wp_xyz:
siro hat geschrieben:a) Der Wert muss nicht in die Formulardatei geschrieben werden, wenn ich ihn im Objektinspektor auf 23 stelle,
jedoch schon, wenn ich ihn auf 24 oder 22 oder xxx stelle.
Damit erkläre ich quasi eine Ausnahmesituation um ein paar Bytes zu sparen ?

Ja. Ein weiterer Nutzen ist, dass man den Default-Wert einmalig ändern kann und er von allen Formularen übernommen wird wenn im Objektinspektor nichts anderes eingetragen wurde. Zudem sieht man im Objektinspektor welche Eigenschaften nicht mehr die Originalwerte enthalten.
b) der Wert wäre Null wenn ich ihn im Constructor NICHT initialisiere,
obwohl default auf 23 steht ? Hab ich das so richtig verstanden ?

Ja.
Wenn ich den Default auf 0 setze zwinge ich ihn dazu den Wert generell ins die Formulardatei zu schreiben ?

Nein, dann wird nichts in die Formulardatei geschrieben, wenn der Wert 0 beträgt. "default 0" sollte dann geschrieben werden, wenn im Konstruktor nichts verändert wird.
Dann ist der Defaultwert eigentlich nur eine Ausnahmesituation wo er ein paar Bytes sparen kann
Wofür braucht man denn so etwas ?

Um viele mal ein paar Bytes zu sparen. ;-)

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: property default

Beitrag von siro »

Okay, da gebe ich Euch natürlich recht, bei umfangreichen Projekten/Listen usw. kann da schon einiges zusammenkommen.

Dann folgere ich aus deinem Text:

Die Reihenfolge ist Constructor initialisert als erstes und dann wird in der .lfm Datei geschaut
ob die Werte evtl. überschrieben werden sollen.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: property default

Beitrag von wp_xyz »

Genau

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: property default

Beitrag von siro »

Okay, nu bin ich wieder etwas schlauer geworden,
habt Dank und einen schönen Abend.
Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: property default

Beitrag von siro »

Da es direkt zu diesem "meinem älteren" Thread passt, wollte ich keinen neuen aufmachen
und würde euch gerne noch einmal bemühen um mein Verständnis zu erweitern:

property default bei Floats

Wenn ich in meinen Komponenten Floats in den "Propertys" einbaue (Single/Double/Extended/Real...), dann gibt es anscheinend keinen "Default",
zumindest werde ich dann angemeckert beim compilieren wenn ich es versuche.

Damit werden also generell alle Floats in den Stream geschrieben ? ist das so ?
Die Initialisierung erfolgt aber wie gehabt direkt im Contructor ?

Mir fehlt da jetzt so ein bischen der Sinn dieser Vorgehensweise, warum werden Floats anders behandelt ?
Aber Ihr habt sicher eine Erklärung dafür.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: property default

Beitrag von wp_xyz »

Ich weiß nicht, warum das so ist bzw. sein muss, aber Floating-Point-Werte können in der Property-Deklaration kein Attribut "default" haben. Dennoch kann man mit Hilfe der "stored"-Direktive das Speichern eines Float-Default-Werts in der lfm-Datei verhindern:

Code: Alles auswählen

const
  DEFAULT_FLOAT_VALUE = 32.456;
 
type
  TMyComponent = class(T<irgendwas>)
  private
    FFloatValue: Double;
    function IsFloatValueStored: boolean;
  public
    constructor Create(AOwner: TComponent);
  publshed
    property  FloatValue: Double read FFloatValue write FFloatValue stored IsFloatValueStored;
  end;
 
constructor TMycomponent.Create(AOwner: TComponent);
begin
  inherited;
  FFloatValue := DEFAULT_FLOAT_VALUE;
end;
 
// Nur wenn IsFloatValueStored true zurückgibt, wird FFloatValue in der lfm-Datei gespeichert.
function TMycomponent.IsFloatValueStored: Boolean;
begin
  Result := FFloatValue <> DEFAULT_FLOAT_VALUE;
end;

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: property default

Beitrag von siro »

Super, vielen Dank wp_xyz
Das ist ja ein "interesanter" Trick,
den Zusatz "stored" kannte ich noch garnicht.
Damit hat sich ja das Problem ja dann komplett erledigt, erstaunlich nur, dass man hier erst selbst Hand anlegen muss.

Ich danke Dir
Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Antworten