Wieso ist property nicht änderbar ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Im folgendem Beispiel, kann ich problemlos auf Int zugreifen, aber auf Rect.Top nicht.
Wieso ist dies so ?

Code: Alles auswählen

  TForm1 = class(TForm)
  ....
  private
    FInt: Integer;
    FRect: TRect;
  public
    property Int: Integer read FInt write FInt;
    property Rect: TRect read FRect write FRect;
  end;

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  FInt := 123;  // geht
  Int := 123;   // geht
  FRect.Top := 123;  // geht
  Rect.Top := 123;   // geht nicht
end;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Wieso ist property nicht änderbar ?

Beitrag von Socke »

Mathias hat geschrieben:
Mi 23. Sep 2020, 15:25
Im folgendem Beispiel, kann ich problemlos auf Int zugreifen, aber auf Rect.Top nicht.
Wieso ist dies so ?
Weil Rect ein Record ist. An Properties kann man immer nur den ganzen Datentyp übergeben. Du änderst ja auch nicht das höchstwertige Byte des Integers.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hi!

Geht nicht gibt's nicht.

Wenn man wieder von diesem umständlichen Klassenzeugs genervt ist, kann man das auch anders machen.

Trect ist definiert als

Left,Top,Right,Bottom : Longint;

Top ist also der zweite Integer in dem Record.

Code: Alles auswählen


procedure TForm1.TestClick(Sender: TObject);
var Oben : integer = 10;
      P : PInteger;
begin
 P := @Rect;
 inc(P);
move(Oben,P^ ,4);
end;            
Wir holen uns die Adresse von der Property Rect.
Wir incrementieren den Adress-Zeiger um eins auf Top.
Wir schieben die Variable Oben nach Rect.Top.
Top hat jetzt den Wert 10.

Es verkürzt den Code und man kann es auch benutzen, wenn irgendwelche Properties readonly sind,
also nur einen Getter aber keinen Setter haben.

Steht so nicht im Lehrbuch, aber wenn man ein bischen nachdenkt ....

Winni

PS: Wieso nimmt der Editor nicht Ctrl-B und Ctrl-I für Bold und Italic???

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Wieso ist property nicht änderbar ?

Beitrag von m.fuchs »

Winni hat geschrieben:
Mi 23. Sep 2020, 22:51
Wenn man wieder von diesem umständlichen Klassenzeugs genervt ist, kann man das auch anders machen.
Wenn man von dem umständlichen Klassenzeugs genervt ist kann man auch zu C oder Assembler wechseln, bevor man wild mit Pointern um sich schießt.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hi!

Pascal ist die durchdachtetste Sprache die ich kenne.

Nur die Delphi-Implementierung der Klassen ist zu wenig durchdacht und zu komplex.
Hätten sie sich mal Modula/Oberon als Vorbild nehmen sollen .

Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Wieso ist property nicht änderbar ?

Beitrag von m.fuchs »

Das kann man so sehen und Kritik an der Sprache ist ja auch kein Problem.
Wichtig ist aber, dass es eine weitgehend vernünftige Objektorientierung gibt und man damit nachhaltige Entwicklung betreiben kann.

Dein Code ist übrigens nicht nachhaltig, er arbeitet mit internen Definition und nicht mit der Schnittstelle. Wenn sich der Aufbau von TRect ändert, dann wird er nicht mehr funktionieren.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

m.fuchs hat geschrieben:
Mi 23. Sep 2020, 23:16

Dein Code ist übrigens nicht nachhaltig, er arbeitet mit internen Definition und nicht mit der Schnittstelle. Wenn sich der Aufbau von TRect ändert, dann wird er nicht mehr funktionieren.
Hi!

Das ist ja völlig richtig, aber dann klauen wir uns mal bei den Soziologen "die normative Kraft des Faktischen":
Das TRect gibt es seit es Records gibt. Und es gibt es wahrscheinlich solange es mindestens zwei Dimensionen gibt.

Und es hat sich reichlich verändert: kann jetzt CenterPoint, IntersectsWith und vieles mehr.
Aber eins ist geblieben:

Left,Top,Right,Bottom

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Wieso ist property nicht änderbar ?

Beitrag von fliegermichl »

@winni
Was machst du, wenn die Rect Property mittels Getter/Setter aus irgendwelchen internen Feldern zusammengesetzt / gespeichert wird?
Das ist genau der Grund weshalb der Compiler Zugriffe auf einzelne Inhalte der Property nicht zuläßt.

Gruß
Michl

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Wieso ist property nicht änderbar ?

Beitrag von Timm Thaler »

m.fuchs hat geschrieben:
Mi 23. Sep 2020, 22:55
[Wenn man von dem umständlichen Klassenzeugs genervt ist kann man auch zu C oder Assembler wechseln, bevor man wild mit Pointern um sich schießt.
Forum! Ich will für sowas einen Like-Button!

Aber ich hätte auch gern eine Erklärung, ich hab nur eine leise Ahnung warum es nicht geht.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Wieso ist property nicht änderbar ?

Beitrag von Timm Thaler »

m.fuchs hat geschrieben:
Mi 23. Sep 2020, 23:16
Dein Code ist übrigens nicht nachhaltig, er arbeitet mit internen Definition und nicht mit der Schnittstelle. Wenn sich der Aufbau von TRect ändert, dann wird er nicht mehr funktionieren.
Nicht nur das: Er ist auch falsch. TRect beinhaltet laut rtl-docs LongInt (4 Byte), und das ist nur zufällig auf aktuellen Rechnern gleich Integer (2 oder 4 Byte).

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Wieso ist property nicht änderbar ?

Beitrag von theo »

fliegermichl hat geschrieben:
Do 24. Sep 2020, 06:05
Was machst du, wenn die Rect Property mittels Getter/Setter aus irgendwelchen internen Feldern zusammengesetzt / gespeichert wird?
Genau, bzw. wenn es gar keinen Setter gibt, bzw nicht geschrieben werden darf?
Rect.Top := 123;
benutzt ja den Getter, nicht den Setter. Es wird ja kein TRect geschrieben, sondern geholt.
Mit einer temporären Variablen kann man korrekt arbeiten und es ist richtig so, obwohl es umständlich erscheint.

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Winni hat geschrieben:
Mi 23. Sep 2020, 22:51
Hi!

Geht nicht gibt's nicht.

Wenn man wieder von diesem umständlichen Klassenzeugs genervt ist, kann man das auch anders machen.

Trect ist definiert als

Left,Top,Right,Bottom : Longint;

Top ist also der zweite Integer in dem Record.

Code: Alles auswählen


procedure TForm1.TestClick(Sender: TObject);
var Oben : integer = 10;
      P : PInteger;
begin
 P := @Rect;
 inc(P);
move(Oben,P^ ,4);
end;            
Wir holen uns die Adresse von der Property Rect.
Wir incrementieren den Adress-Zeiger um eins auf Top.
Wir schieben die Variable Oben nach Rect.Top.
Top hat jetzt den Wert 10.

Es verkürzt den Code und man kann es auch benutzen, wenn irgendwelche Properties readonly sind,
also nur einen Getter aber keinen Setter haben.

Steht so nicht im Lehrbuch, aber wenn man ein bischen nachdenkt ....

Winni

PS: Wieso nimmt der Editor nicht Ctrl-B und Ctrl-I für Bold und Italic???
Bevor ich sowas bastle, werde ich Rect direkt in public deklarieren.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 830
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Wieso ist property nicht änderbar ?

Beitrag von PascalDragon »

Winni hat geschrieben:
Mi 23. Sep 2020, 22:51

Code: Alles auswählen


procedure TForm1.TestClick(Sender: TObject);
var Oben : integer = 10;
      P : PInteger;
begin
 P := @Rect;
 inc(P);
move(Oben,P^ ,4);
end;            
Das funktioniert nicht, wenn Rect eine Methode als Getter hat, da du dann auf einer temporären Variable arbeitest.
FPC Compiler Entwickler

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hi!

Funktioniert wunderbar:

Code: Alles auswählen

TForm1 = class(TForm)
  private
  Frect : TRect;
  public
  property MyRect: TRect read FRect write FRect;
  published      
  Image1: TImage;
  Test: TButton;
  procedure TestClick(Sender: TObject);
  procedure Image1Paint(Sender: TObject); 
.....
end;

procedure TForm1.TestClick(Sender: TObject);
var Oben : integer = 10;
    P : PInteger;
begin
 MyRect := Rect(100,100,200,200);
 Image1.Invalidate;
 showMessage ('Nun Top auf 10');
 P := @MyRect;
 inc(p);
 move(Oben,P^ ,4);
 Image1.Invalidate;
 end;
 
procedure TForm1.Image1Paint(Sender: TObject);
begin
 Image1.Canvas.Brush.Color := clAqua;
 Image1.Canvas.Rectangle(MyRect);
end;
Winni

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Wieso ist property nicht änderbar ?

Beitrag von theo »

Warum so kryptisch?
Wenn das Property nun mal ein TRect ist, dann ist die saubere Lösung mMn eine temp.Var.

Code: Alles auswählen

var tmpRct:TRect;
begin
 tmpRct:=MyRect;
 Inc(tmpRct.top,1);
 MyRect:=tmpRct;
end;   
Vielleicht ist der Record aber auch schlicht nicht der ideale Datentyp für einen Property Setter.

Antworten