Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi typecast in neuen Delphi-Versionen (https://www.delphipraxis.net/186930-typecast-neuen-delphi-versionen.html)

BadenPower 13. Okt 2015 16:21

Delphi-Version: XE8

typecast in neuen Delphi-Versionen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Da ich mich schon einige Zeit mit dem Gedanken beschäftige von Delphi eventuell auf Lazarus umzusteigen (anstelle einer Neuanschaffung von Delphi / bisher D2007) ist mir im Lazarus-Forum ein Beitrag aufgefallen, welcher für meine Überlegung sehr interessiert ist, da ich zum Teil exzessiv Typecasts einsetze.

Hier einmal der Link:
http://www.lazarusforum.de/viewtopic.php?f=18&t=9105


Die Ausgangssituation mit einer erweiterten Komponente:
Delphi-Quellcode:
type
  TMyEdit = class(TEdit)
   private
    FEnhReadOnly: Boolean;
    function GetEnhReadOnly(): Boolean; virtual;
    procedure SetEnhReadOnly(AValue: Boolean); virtual;
   public
    constructor Create(AOwner: TComponent); override;
   published
    property ReadOnly: Boolean read GetEnhReadOnly write SetEnhReadOnly;
  end;

implementation

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEnhReadOnly := inherited ReadOnly;
end;

function TMyEdit.GetEnhReadOnly(): Boolean;
begin
  Result := FEnhReadOnly;
end;

procedure TMyEdit.SetEnhReadOnly(AValue: Boolean);
begin
  if (FEnhReadOnly <> AValue) then
   begin
    FEnhReadOnly := AValue;
   end;
end;
und darauf folgenden Zugriff:

Delphi-Quellcode:
MyEdit1 := TMyEdit.Create(Self);
MyEdit1.ReadOnly := true;

lBoolean := MyEdit1.ReadOnly           //Result: true
lBoolean := TEdit(MyEdit1).ReadOnly    //Result: false
lBoolean := (MyEdit1 as TEdit).ReadOnly //Result: true
So ist es zum Beispiel auch bei mir mit Delphi2007 aus.

Wie sieht es in den aktuellen Delphi-Versionen aus?

Oder wird seit neuestem bei
Delphi-Quellcode:
(MyEdit1 as TEdit).ReadOnly
auch false zurückgegeben wie scheinbar bei Lazarus?

Den Original-Quellcode habe ich einmal ausgeborgt und angehängt.
Wäre nett, wenn dies jemand testen könnte.

uligerhardt 13. Okt 2015 17:17

AW: typecast in neuen Delphi-Versionen
 
Zitat:

Zitat von BadenPower (Beitrag 1318570)
Delphi-Quellcode:
lBoolean := TEdit(MyEdit1).ReadOnly    //Result: false
lBoolean := (MyEdit1 as TEdit).ReadOnly //Result: true

Weia. Ist mir nie aufgefallen. Das ist ja daneben - Cast sollte in diesem Fall Cast sein.

Edit: In XE6 funktioniert's, wie es sollte - also anders, als du es gerne hättest. :mrgreen:

SMO 13. Okt 2015 17:28

AW: typecast in neuen Delphi-Versionen
 
Interessantes Problem.

In Delphi XE6:

Delphi-Quellcode:
lBoolean := MyEdit1.ReadOnly //Result: true
lBoolean := TEdit(MyEdit1).ReadOnly //Result: false
lBoolean := (MyEdit1 as TEdit).ReadOnly //Result: false
So, wie es meiner Meinung nach auch sein sollte. Es gibt keinen "Softcast" wie im Lazarusforum jemand annahm.

In obigem Beispiel generiert XE6 übrigens erst gar keinen Code, der die Klasse von MyEdit1 prüft, weil die ja schon zur Compilezeit ersichtlich ist.
Man könnte den Test also noch so erweitern:

Delphi-Quellcode:
var Obj: TObject;
Obj := MyEdit1;
lBoolean := MyEdit1.ReadOnly //Result: true
lBoolean := TEdit(MyEdit1).ReadOnly //Result: false
lBoolean := (MyEdit1 as TEdit).ReadOnly //Result: false
lBoolean := (Obj as TEdit).ReadOnly //Result: false
lBoolean := (Obj as TMyEdit).ReadOnly //Result: true

BadenPower 13. Okt 2015 18:07

AW: typecast in neuen Delphi-Versionen
 
Zitat:

Zitat von uligerhardt (Beitrag 1318577)
In XE6 funktioniert's, wie es sollte - also anders, als du es gerne hättest. :mrgreen:

Das ist so nicht richtig ausgedrückt.

Denn unter XE6 funktioniert es anderst, denn ich hatte bisher angenommen, dass es bislang so funktioniert wie es sollte.

Dann bleib' ich doch bei Delphi2007, denn da funktioniert es so wie ich es brauche und seit je her gewohnt bin.


Aber wenn ich mir so das Lazarus-Forum anschaue und mit hier vergleiche, dann wird es arbeitstechnisch egal sein, ob ich in nächster Zeit mit Lazarus anfange oder eine neue Delphi-Version erstehe.

stoxx 14. Okt 2015 08:48

AW: typecast in neuen Delphi-Versionen
 
Zitat:

Zitat von BadenPower (Beitrag 1318581)
Zitat:

Zitat von uligerhardt (Beitrag 1318577)
In XE6 funktioniert's, wie es sollte - also anders, als du es gerne hättest. :mrgreen:

Das ist so nicht richtig ausgedrückt.

Denn unter XE6 funktioniert es anderst, denn ich hatte bisher angenommen, dass es bislang so funktioniert wie es sollte.
Dann bleib' ich doch bei Delphi2007, denn da funktioniert es so wie ich es brauche und seit je her gewohnt bin.


Also wenn ich auf "Deklaration suchen" gehe von:

Delphi-Quellcode:
(MyEdit1 as TEdit).ReadOnly
Dann verweist Delphi XE8 korrekt auf Vcl.StdCtrls

Unter Delphi 2007 geht die Deklaration (fehlerhaft) auf TMyEdit.ReadOnly

Also ist es ein Bug von Delphi 2007, der irgendwann behoben wurde.
Schreib Deinen Code doch lieber um, so dass er logisch korrekt auch unter XE funktioniert.

.

BadenPower 14. Okt 2015 10:59

AW: typecast in neuen Delphi-Versionen
 
Zitat:

Zitat von stoxx (Beitrag 1318629)
Schreib Deinen Code doch lieber um, so dass er logisch korrekt auch unter XE funktioniert.

Umschreiben ist immer mit Aufwand verbunden.

Klar könnte ich zum Beispiel GetPropValue einsetzen, was mir dann auch die richtigen Werte ausgeben würde.

Allerdings müsste ich dann für die abzufragenden Properties feste Strings verwenden, worauf ich eigentlich verzichten wollte.

1. können Tippfehler entstehen
2. merkt man erst zur Laufzeit dass eine Property für dieses Objekt nicht exisiert.

samso 14. Okt 2015 11:34

AW: typecast in neuen Delphi-Versionen
 
Wenn ich bei Delphi 2007..2010 (andere Versionen nicht getestet) folgendes formuliere:

Delphi-Quellcode:
function GetReadOnly(AEdit: TEdit): Boolean;
begin
  Result := AEdit.ReadOnly;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  Memo1.Lines.Add('MyEdit1.ReadOnly           : ' + BoolToStr(MyEdit1.ReadOnly, True));
  Memo1.Lines.Add('TEdit(MyEdit1).ReadOnly    : ' + BoolToStr(TEdit(MyEdit1).ReadOnly, True));
  Memo1.Lines.Add('(MyEdit1 as TEdit).ReadOnly : ' + BoolToStr((MyEdit1 as TEdit).ReadOnly, True));
  Memo1.Lines.Add('GetReadOnly(MyEdit1)       : ' + BoolToStr(GetReadOnly(MyEdit1), True));
  Memo1.Lines.Add('');
end;
ergibt das folgende Ausgabe:
Code:
MyEdit1.ReadOnly            : True
TEdit(MyEdit1).ReadOnly     : False
(MyEdit1 as TEdit).ReadOnly : True
GetReadOnly(MyEdit1)        : False
:shock:

uligerhardt 14. Okt 2015 12:20

AW: typecast in neuen Delphi-Versionen
 
Zitat:

Zitat von samso (Beitrag 1318659)
Code:
MyEdit1.ReadOnly            : True
TEdit(MyEdit1).ReadOnly     : False
(MyEdit1 as TEdit).ReadOnly : True
GetReadOnly(MyEdit1)        : False
:shock:

Ist doch klar:
  • Bei 1 ist die Variable vom statischen Typ TMyEdit, also kommt True. Passt.
  • Bei 2 und 4 ist der statische Typ TEdit, aber der dynamische TMyEdit. Wichtig ist aber der statische Typ, also False. Passt auch.
  • 3 sollte wie 2 laufen, wegen des Bugs kommt aber True.


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