AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Control zuweisen

Ein Thema von MicMic · begonnen am 30. Jan 2021 · letzter Beitrag vom 2. Feb 2021
Antwort Antwort
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Control zuweisen

  Alt 30. Jan 2021, 14:41
Delphi-Version: 10.3 Rio
Hallo,
ich mache das recht oft aber bin mir eigentlich nicht sicher, ob das Nachteile hat.
Als Beispiel für eine ListBox in OnDrawItem:
Delphi-Quellcode:
Procedure ... DrawItem(Control: TWinControl; Index: Integer;...
Var L : TListBox;
Begin
  L := TListBox(Control);
  If L.Columns = 0 Then...
End;
Also ich mache sowas gerne, damit der weitere Verlauf im Code abgekürzt ist. Nicht nur bei einer ListBox. Sonst müsste ich in diesem Fall immer "TListBox(Control)." angeben. So ein DrawItem-Ereignis wird ja oft aufgerufen und die zuweisen erfolgt dann natürlich auch immer sehr oft. Aber denke das ist ok so. Man könnte z.B. noch die Zeile "Var L : TListBox;" Global setzen. Wenn ich darauf achte, dass diese Variable "L" nicht woanders genutzt wird, würde dies dann für "OnDrawItem" ein Vorteil sein? Oder ist das ganz egal? Zuweisen muss ich ja sowieso aber das "Var L : TListBox;" wäre dann woanders. Jedenfalls bringt es mir viel im Code (für die Übersicht):
Delphi-Quellcode:
  If Index = Ceil(TListBox(Control).ClientHeight / TListBox(Control).ItemHeight)-1+TListBox(Control).TopIndex Then // langer Code
  If Index = Ceil(L.ClientHeight / L.ItemHeight)-1+L.TopIndex Then // kurzer Code

Geändert von MicMic (30. Jan 2021 um 14:42 Uhr) Grund: Delphi-Version geändert
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Control zuweisen

  Alt 30. Jan 2021, 14:59
Für den Compiler ist es komplett egal und auch vom erzeugten Code ergibt es praktisch keinen Unterschied,

also ob du auf die eine Variable mit einem Casts zugreifst,
oder ob das nur einmal in eine andere Variable kopiert und dann Jene benutzt.

Einen Unterschied gibt es bei harten Cast TListBox(Control) gegenüber einem weichen Cast (Control as TListBox) .
Falls mehrmal genutzt und der Weiche, mit "Prüfung" ob der Typ in der Variable wirklich passt, nötig ist, dann braucht man nur beim ersten Zugriff einen Weichen und es kann später Hart sein, da es sich ja nicht ändern wird.


PS:
Delphi-Quellcode:
Procedure ... DrawItem(Control: TWinControl; Index: Integer;...
Var L : TListBox absolute Control;
Begin
  If L.Columns = 0 Then...
End;
L ist ein "Alias" für den Speicherplatz von Control (kann/darf auch ein anderer Typ sein, aber nur gleichgroß oder kleiner, wie der originale Typ)

Dein L ist eine Kopie (des Objektzeiger/Pointer) und mit absolute ist es die "gleiche" Variable.


oder ... aber das will niemand machen
Delphi-Quellcode:
begin
  with TListBox(Control) do
    if Columns = 0 then...
end;
$2B or not $2B

Geändert von Daniel (31. Jan 2021 um 17:33 Uhr) Grund: // Tippfehler auf Wunsch des Autors korrigiert
  Mit Zitat antworten Zitat
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Control zuweisen

  Alt 30. Jan 2021, 15:11
Danke. "L" war nur ein Beispiel. Nutze es nicht nur bei einer ListBox. Hier in diesem Fall nehme ich "LB" als Variable.
In vielen Code-Bereichen wird der Code dann einfach etwas übersichtlicher
Wenn es Delphi wurscht ist, lasse ich die "Var-Zeile", da wo es sie ist.
Vielen Dank
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#4

AW: Control zuweisen

  Alt 31. Jan 2021, 06:42
...
oder ... aber das will niemand machen
Delphi-Quellcode:
begin
  while TListBox(Control) do
    if Columns = 0 then...
end;
Du meintest sicher:
Delphi-Quellcode:
begin
  with TListBox(Control) do
  begin
    if Columns = 0 then
    ...
  end;
end;
oder?

Habe ich mir aber abgewöhnt, da man immer aufpassen muss nicht die falsche Variable / Funktion zu erwischen. Lieber etwas mehr tippen. Es ist dann auch einfacher Code-Fragmente zu kopieren...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: Control zuweisen

  Alt 31. Jan 2021, 16:41
ups, ja WITH.


Ich hatte z.B. in etwa folgenden Code in einer TForm gesehn:
Als Kommentare das, was der Entwickler sich dabei dachte, bzw. was der Compiler neuerdings daraus machte.
Delphi-Quellcode:
var Rect: TRect;

with Rect do
  {Self.}Width := {Rect.}Right - {Rect.}Left;
Das funktionierte super, so lange sich nichts veränderte und TRect so aussah
Delphi-Quellcode:
  TRect = record
    Left, Top, Right, Bottom: Integer;
  end;

  //bzw.
  TRect = record
  case Integer of
    0: (Left, Top, Right, Bottom: Integer);
    1: (TopLeft, BottomRight: TPoint);
  end;
Und dann wunderte man sich, dass der Code plötzlich nicht mehr funktionierte und die Form ihre Größe nicht mehr anpasste, denn
Delphi-Quellcode:
var Rect: TRect;

with Rect do
  {Rect.}Width := {Rect.}Right - {Rect.}Left;
Delphi-Quellcode:
  TRect = record
  ...
  public
    ...
    property Width: Integer read GetWidth write SetWidth;
    ...
  case Integer of
    0: (Left, Top, Right, Bottom: FixedInt);
    1: (TopLeft, BottomRight: TPoint);
  end;
Auch TForm und andere Komponenten/Klassen bekommen irgendwann mal neue Funktionen, an die niemand damals dachte.

Zitat:
Delphi-Quellcode:
  TRect = record
  private
    function GetWidth: Integer;
    procedure SetWidth(const Value: Integer);
    function GetHeight: Integer;
    procedure SetHeight(const Value: Integer);
    function GetSize: TSize;
    procedure SetSize(const Value: TSize);
    function GetLocation: TPoint;
  public
    constructor Create(const Origin: TPoint); overload; // empty rect at given origin
    constructor Create(const Origin: TPoint; Width, Height: Integer); overload; // at TPoint of origin with width and height
    constructor Create(const Left, Top, Right, Bottom: Integer); overload; // at Left, Top, Right, and Bottom
    constructor Create(const P1, P2: TPoint; Normalize: Boolean = False); overload; // with corners specified by p1 and p2
    constructor Create(const R: TRect; Normalize: Boolean = False); overload;

    // operator overloads
    class operator Equal(const Lhs, Rhs: TRect): Boolean;
    class operator NotEqual(const Lhs, Rhs: TRect): Boolean;

    // union of two rectangles
    class operator Add(const Lhs, Rhs: TRect): TRect;

    // intersection of two rectangles
    class operator Multiply(const Lhs, Rhs: TRect): TRect;

    class function Empty: TRect; inline; static;

    //utility methods
    //makes sure TopLeft is above and to the left of BottomRight
    procedure NormalizeRect;

    //returns true if left = right or top = bottom
    function IsEmpty: Boolean;

    //returns true if the point is inside the rect
    function Contains(const Pt: TPoint): Boolean; overload;

    // returns true if the rect encloses R completely
    function Contains(const R: TRect): Boolean; overload;

    // returns true if any part of the rect covers R
    function IntersectsWith(const R: TRect): Boolean;

    // computes an intersection of R1 and R2
    class function Intersect(const R1: TRect; const R2: TRect): TRect; overload; static;

    // replaces current rectangle with its intersection with R
    procedure Intersect(const R: TRect); overload;

    // computes a union of R1 and R2
    class function Union(const R1: TRect; const R2: TRect): TRect; overload; static;

    // replaces current rectangle with its union with R
    procedure Union(const R: TRect); overload;

    // creates a minimal rectangle that contains all points from array Points
    class function Union(const Points: Array of TPoint): TRect; overload; static;

    // offsets the rectangle origin relative to current position
    procedure Offset(const DX, DY: Integer); overload;
    procedure Offset(const Point: TPoint); overload;

    // sets new origin
    procedure SetLocation(const X, Y: Integer); overload;
    procedure SetLocation(const Point: TPoint); overload;

    // inflate by DX and DY
    procedure Inflate(const DX, DY: Integer); overload;

    // inflate in all directions
    procedure Inflate(const DL, DT, DR, DB: Integer); overload;

    //returns the center point of the rectangle;
    function CenterPoint: TPoint;

    function SplitRect(SplitType: TSplitRectType; Size: Integer): TRect; overload;
    function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect; overload;

    // changing the width is always relative to Left;
    property Width: Integer read GetWidth write SetWidth;
    // changing the Height is always relative to Top
    property Height: Integer read GetHeight write SetHeight;

    property Size: TSize read GetSize write SetSize;

    property Location: TPoint read GetLocation write SetLocation;

  case Integer of
    0: (Left, Top, Right, Bottom: FixedInt);
    1: (TopLeft, BottomRight: TPoint);
  end;
$2B or not $2B

Geändert von himitsu (31. Jan 2021 um 18:02 Uhr)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
504 Beiträge
 
Delphi 12 Athens
 
#6

AW: Control zuweisen

  Alt 31. Jan 2021, 17:02
Genau das meinte ich. "with" ist immer gefährlich wenn man nicht genau weiß was man macht bzw. wo der Code noch zum Einsatz kommt.

Ich hatte mich früher in C++ aufgeregt, dass es da das "with" in der Form nicht gibt. Mittlerweile bin ich froh drum. Man kann dort aber in ähnliche Probleme mit den "namespaces" laufen...

Aber an besten ausschreiben. Und wenn der Bezeichner in den Parametern doch unmöglich lange ist, dann kann man ja immer noch den Weg über "var x: ... absolute ..." gehen...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.456 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Control zuweisen

  Alt 2. Feb 2021, 09:56
Hallo,
ich mache das recht oft aber bin mir eigentlich nicht sicher, ob das Nachteile hat.
Als Beispiel für eine ListBox in OnDrawItem:
Delphi-Quellcode:
Procedure ... DrawItem(Control: TWinControl; Index: Integer;...
Var L : TListBox;
Begin
  L := TListBox(Control);
  If L.Columns = 0 Then...
End;
Auch nach längerem Überlegen fällt mir fast kein Nachteil ein. Es könnte Fälle geben wo jemand motzt weil eine eine MNethod wegen den zwei Zeilen zu lange ist.
Auf jeden Fall: machs
Die Vorteile vor allem wegen der Übersichtlichkeit überwiegen deutlich.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Control zuweisen

  Alt 2. Feb 2021, 10:03
[QUOTE=freimatz;1481997]
Hallo,
ich mache das recht oft aber bin mir eigentlich nicht sicher, ob das Nachteile hat.
Nein. Ich könnte in diesem Fall auch einen "soften" Cast verwenden, dann ist es sicher sicher.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Control zuweisen

  Alt 2. Feb 2021, 10:26
Ja, das mit Soft und Hart hatte ich schon erwähnt.

Der Gedanke des Grundproblems war aber nicht die Art des Castes (auch wenn da deine Aussage stimmt),
sondern es ging garum den "mehrfachen" Cast vorher in einer Variable zwischenzuspeichern und dann überall die Variable zu verwenden.
* Hier hat die Variable eigentlich mehr Vorteile, gegenüber den 4-8 Byte mehr für die neue Varialbe

* Und ja, wenn man das noch für den soften Cast betrachtet, dann ist "einmal" der Cast, gegenüber Mehrmals noch vorteilhafter.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:02 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