Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   ICH habe den ältesten OOP-Bug entdeckt :firejump: , leider. (https://www.delphipraxis.net/194287-ich-habe-den-aeltesten-oop-bug-entdeckt-firejump-leider.html)

himitsu 6. Nov 2017 15:06

Delphi-Version: XE

ICH habe den ältesten OOP-Bug entdeckt :firejump: , leider.
 
Gegeben sei
Delphi-Quellcode:
type
  TFirstComp = class
  protected
    FTest: string;
    procedure SetTest(Value: string);
  published
    property TestProp: string read FTest write SetTest;
  end;
Da kann man nun die Property-Deklaration überschreiben/ändern:
Delphi-Quellcode:
type
  TSecondComp = class(TFirstComp)
  protected
    function StoredTest(Index: Integer): Boolean;
  published
    property TestProp index 1 stored StoredTest;
  end;
Viele nutzen dass, um den Getter/Setter zu ändern, wenn sich keine Getter/Setter-Methode überschreiben (override) lässt.
Sehr bekannt ist sowas auch für das Ändern des Defaultwertes. Oder zum Verschieben der Sichtbarkeit.

Nur knallt das jetzt, wenn z.B. das Property aus der DFM gelesen wird,
denn Delphi ruft SetTest nun freudig mit zwei Parametern auf, obwohl es nur einen Parameter gibt.


Schon, bissl blöd, dass TReader den "INDEX" aus der aktuellen Implementation verwendet, obwohl es in der Basisklasse garkeinen Index gibt.
Aber OK, dann wäre es zumindestens gut, wenn der Compiler hier wenigstens einen Hinweis oder besser noch einen Fehler mir entgegen werfen täte. :cry: (fast 2 Tage lang gesucht)

Eine Lösung wäre jetzt auch den Setter zu überschreiben:
Delphi-Quellcode:
type
  TSecondBugfixComp = class(TFirstComp)
  protected
    procedure SetTest(Index: Integer; Value: string);
    function StoredTest(Index: Integer): Boolean;
  published
    property TestProp index 1 write SetTest stored StoredTest;
  end;
So geht es erstmal, bis irgendwann TFirstComp auch einen Getter bekommt und es wieder knallt.

Alles überschreiben oder besser noch gleich das alte Property verdecken und durch eine Neudeklaration ersetzen:
Delphi-Quellcode:
type
  TSecondBugfix2Comp = class(TFirstComp)
  protected
    function GetTest(Index: Integer): string;
    procedure SetTest(Index: Integer; Value: string);
    function StoredTest(Index: Integer): Boolean;
  published
    property TestProp: string index 1 read GetTest write SetTest stored StoredTest;
  end;
Eigentlich wollte ich mir Arbeit ersparen und den Code kürzer/übersichtlicher halten, indem ich für mehrere Property nur eine StoredProc verwende, anstatt jeweils eine Eigene.

Stevie 6. Nov 2017 15:16

AW: ICH habe den ältesten OOP-Bug entdeckt :firejump: , leider.
 
Der Bug ist, dass die Property Deklaration mit index aber ohne explizite Angabe von Getter und/oder Setter möglich ist - der Compiler müsste das verhindern, und/oder nicht einfach einen Getter/Setter mit falscher Signatur aufrufen.

Denn das knallt nicht nur beim Lesen aus der dfm sondern auch beim manuellen Setzen:

Delphi-Quellcode:
var
  s: TSecondComp;
begin
  s := TSecondComp.Create;
  s.TestProp := ''; // peng!
Delphi-Quellcode:
Project1.dpr.44: s.TestProp := '';
0041D567 33C9             xor ecx,ecx
0041D569 BA01000000       mov edx,$00000001 // <- index
0041D56E A1A4584200       mov eax,[$004258a4]
0041D573 E86CD2FFFF      call TFirstComp.SetTest


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