Typenumwandlung und as ?

Rund um die LCL und andere Komponenten

Typenumwandlung und as ?

Beitragvon Mathias » 31. Dez 2017, 16:26 Typenumwandlung und as ?

Ich habe da 2 verschiedene Varianten um einen Button auszuwerten. funktionieren tun beide.
Welches ist der Vor- und Nachteil der beiden Varianten ?
Wobei mir ersteres sympatischer erscheint.
Code: Alles auswählen
procedure TForm1.ButtonClick(Sender: TObject);
begin
  if TButton(Sender) = Button2 then begin
    ShowMessage('Button2 gedrückt');
  end;
  if (Sender as TButton) = Button3 then begin
    ShowMessage('Button3 gedrückt');
  end;
end;
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 31. Dez 2017, 17:14 Re: Typenumwandlung und as ?

Um zu prüfen, ob Sender gleich Button2 ist, dafür brauchst du gar keine Typumwandlung, denn sowohl Sender als auch Button2 sind Abkömmlinge von TObject, so dass man die Pointer auf Gleichheit prüfen kann.
Code: Alles auswählen
if Sender = Button2 then ShowMessage('Button2 gedrückt');

Wenn du wissen willst, ob Sender allgemein ein TButton ist oder ein Nachfahre davon (also nicht die Instanz Button2), nimmt man den Operator "is":
Code: Alles auswählen
if (Sender is TButton) then ShowMessage('Es wurde irgendein Button gedrückt.');

"as" prüft dasselbe wie "is", und erzeugt eine Exception "invalid type cast", falls Sender keine Instanz von TButton oder einem Nachfahren ist. Andernfalls wird eine Typumwandlung nach TButton ausgeführt.

Die ungeprüfte, einfache Typumwandlung TButton(Sender) fliegt dir irgendwann unkontrolliert um die Ohren, wenn Sender kein TButton ist, vor allem, wenn schreibend auf die Properties des Nicht-Buttons zugegriffem wird oder dessen Methoden aufgerufen werden.
wp_xyz
 
Beiträge: 2670
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 1. Jan 2018, 16:54 Re: Typenumwandlung und as ?

Code: Alles auswählen
if Sender = Button2 then ShowMessage('Button2 gedrückt');
Das dies so einfach geht, man lernt immer wieder dazu. :shock:

Nur schade, das so etwas nicht geht:
Code: Alles auswählen
  case Sender of
    MenuItemPlus: begin
      if CubeSize < 7 then begin
        Inc(CubeSize);
      end;
    end;
    MenuItemMinus: begin
      if CubeSize > 0 then begin
        Dec(CubeSize);
      end;
    end;
  end;


Dies wäre einige eleganter als die if else Verschachtelung.
Code: Alles auswählen
  if Sender = MenuItemPlus then begin
    if CubeSize < 7 then begin
      Inc(CubeSize);
    end;
  end else if Sender = MenuItemMinus then begin
    if CubeSize > 0 then begin
      Dec(CubeSize);
    end;
  end;


Für das is habe ich auch noch eine Verwendung gefunden.
Code: Alles auswählen
  if (Sender is TButton) then begin
    Label1.Caption := TButton(Sender).Caption;
  end;   
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon theo » 1. Jan 2018, 17:24 Re: Typenumwandlung und as ?

Mathias hat geschrieben:Nur schade, das so etwas nicht geht:


Dafür gibt es genügend Alternativen. Z.B. über den Tag, oder auch so:

Code: Alles auswählen
  case (Sender as TComponent).Name of
     'Button1': begin
       Caption:='b1';
     end;
     'Button2': begin
       Caption:='b2';
     end;
   end;   
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon Mathias » 1. Jan 2018, 17:55 Re: Typenumwandlung und as ?

Wer garantiert dir, das der .Name gleich ist, wie der Variablenname ?
Besonders, wen der Button dynamisch erzeugt wurde.
Diese Procedure spuckt einen Leerstring aus.
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
var
  button: TButton;
begin
  button := TButton.Create(Self);
  button.Parent := Self;
  ShowMessage(button.Name);
end;

Und Tag mit irgendwelchen Nummern ist recht fehleranfällig.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon kupferstecher » 1. Jan 2018, 18:21 Re: Typenumwandlung und as ?

Mathias hat geschrieben:Nur schade, das so etwas nicht geht:

Ich bevorzuge zwar sowieso if...elsen, aber wuerde es so nicht gehen?

Code: Alles auswählen
  case ptruint(Sender) of
    ptruint(MenuItemPlus): begin
    ...
kupferstecher
 
Beiträge: 165
Registriert: 17. Nov 2016, 11:52

Beitragvon theo » 1. Jan 2018, 18:30 Re: Typenumwandlung und as ?

Mathias hat geschrieben:Wer garantiert dir, das der .Name gleich ist, wie der Variablenname ?

Der Programmierer? Spielt doch keine Rolle.
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon theo » 1. Jan 2018, 18:32 Re: Typenumwandlung und as ?

kupferstecher hat geschrieben:
Mathias hat geschrieben:Nur schade, das so etwas nicht geht:

Ich bevorzuge zwar sowieso if...elsen, aber wuerde es so nicht gehen?

Code: Alles auswählen
  case ptruint(Sender) of
    ptruint(MenuItemPlus): begin
    ...


Nein, unten muss es eine Konstante sein.
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon Mathias » 1. Jan 2018, 20:17 Re: Typenumwandlung und as ?

Irgendwie komisch, das case mit Strings funktioniert, aber nicht mit Classen, obwohl dies nur Pointer(Integer) sind.
Dies wäre sicher eine gute Features-Erweiterung.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon theo » 1. Jan 2018, 20:40 Re: Typenumwandlung und as ?

Wie gesagt, der Vergleich (nach dem of) muss eine Konstante sein.

'Button1' ist eine Stringkonstante, Button1 ist aber keine Konstante. Du weißt ja nicht vor dem Kompilieren und Ausführen, welche Speicheradresse Button1 bekommt, sonst könnte man da theoretisch auch eine Zahl angeben.

Die sauberste Variante ist wahrscheinlich die mit dem Tag.
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon Mathias » 1. Jan 2018, 20:51 Re: Typenumwandlung und as ?

Wie gesagt, der Vergleich (nach dem of) muss eine Konstante sein.

Das habe ich übersehen, jetzt ist der Fall klar. :oops:
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon wp_xyz » 1. Jan 2018, 21:38 Re: Typenumwandlung und as ?

Code: Alles auswählen
  if (Sender = MenuItemPlus) and (CubeSize < 7) then 
    Inc(CubeSize)
  else if (Sender = MenuItemMinus) and (CubeSize > 0) then
    Dec(CubeSize);

... wäre dich auch ganz schön kompakt
wp_xyz
 
Beiträge: 2670
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 1. Jan 2018, 22:07 Re: Typenumwandlung und as ?

Das CubeSize ist nur ein Beispiel.
Was störend wirkt, wen man mehrer Menupunkte abfragen muss und dabei muss der Bezeichner Sender zig mal stehen.
Ein Case of würde sowas viel übersichtlicher machen. Ich denke, es wäre sicher möglich FPC zu modifizieren, das sowas auch geht.
Ein normales case of arbeitet intern auch mit (if then else ) oder mit jmp, jp, etc.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4342
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried