Autor Beitrag
Mitmischer 1703
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 13:30 
Wofür gibt es den Is-Operator?

Edit: Arrgh *drauf geh* Ich hab meinen 400.Post verpasst! :schmoll: *schmoll*

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 14:34 
Damit prüfst du ob ein Objekt ein bestimmter Typ ist. Zum Beispiel wird in den ganzen Events immer Sender: TObject mit übergeben. Darin steckt das Objekt, das dieses Ereignis ausgelöst hat. Bei einem Buttonclick also der Button, von dem es kommt. Wenn du jetzt aber das selbe Event von einem TButton und einem TBitButton aufrufst, kannst du nicht einfach nach TButton casten, an der Stelle musst du dann feststellen was da als Objekt übergeben wurde.

Praktisches Beispiel:
Nimm mal zwei Buttons und schreibe beim ersten im OnClick:
ausblenden Delphi-Quelltext
1:
(Sender as TButton).Caption := 'geklickt';					
Jetzt gehe in den Objektinspektor und weise dem OnClick des zweiten Buttons manuell das Event des ersten zu. Das Ergebnis ist, dass du nur eine Prozedur zur Behandlung beider Klicks hast.

Du kannst diese Methode aber auch selbst aufrufen mit Button1Click(Button1);. Du kannst dort aber auch ein anderes Objekt angeben und dann im Klick unterscheiden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
if Sender is TButton then
  (Sender as TButton).Caption := 'geklickt'
else
  ShowMessage('Anders aufgerufen');
Schreibe das einmal in deine OnClick Routine, erstelle einen weiteren Button und schreibe dort hinein:
ausblenden Delphi-Quelltext
1:
Button1Click(Form1);					

Ergebnis: Wird das Button1Click bei dem Event aufgerufen durch die beiden Buttons, dann wird deren Caption geändert, rufst du es manuell durch den dritten Button auf, dann übergibst du keinen Button und deshalb kommt die MessageBox.
Mitmischer 1703 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 15:06 
Aber kann man nicht mit
ausblenden Delphi-Quelltext
1:
if Button1.Type = TButton					

(oder etwas ähnlichem) überprüfen?

Die Sache mit dem as-Operator versteh ich aber nicht ganz... Nimmt man damit eine Typverwandlung vor. Also: Tu so als ob Sender gleich TButton wäre und führe dann >>bla, bla<< aus - Und bla, bla ist spezielle Funktion von TButton?!:?:?:?

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 15:24 
user profile iconMitmischer 1703 hat folgendes geschrieben Zum zitierten Posting springen:
Aber kann man nicht mit
ausblenden Delphi-Quelltext
1:
if Button1.Type = TButton					

(oder etwas ähnlichem) überprüfen?
Dabei lässt du außer Acht, dass eine Klasse oft mehrere Vorfahren hat. So kannst du nur die letzte prüfen, nicht aber ob es sich zum Beispiel um einen Nachfahren von TControl oder TWinControl handelt. Du kannst mit is das prüfen um etwas mit mehreren Komponententypen zu machen. Zum Beispiel Visible ändern, egal ob es ein TButton oder ein TMemo ist.
Nebenbei: Es heißt ClassType ;-).

Als Beispiel, TButton und TMemo mit folgender OnClick-Routine:
ausblenden Delphi-Quelltext
1:
2:
  if Sender is TWinControl then
   TWinControl(Sender).Visible := False;
Mit ClassType könntest du nur auf den speziellen Typ prüfen, nicht aber auf den gemeinsamen Vorfahren TWinControl.

An dieser Stelle kannst du mit TWinControl(Sender) direkt casten, weil du ja vorher geprüft hast, dass es sich um diesen Typ handelt.
Wenn du as benutzt wird vorher geprüft ob der Typecast überhaupt möglich ist.

user profile iconMitmischer 1703 hat folgendes geschrieben Zum zitierten Posting springen:
Die Sache mit dem as-Operator versteh ich aber nicht ganz... Nimmt man damit eine Typverwandlung vor. Also: Tu so als ob Sender gleich TButton wäre und führe dann >>bla, bla<< aus - Und bla, bla ist spezielle Funktion von TButton?!:?:?:?
Richtig, der in einer allgemeinen Variable z.B. vom Typ TObject gespeichert ist, soll wieder als TButton behandelt werden, denn wenn du die Variable ohne Typecast benutzt, dann weiß Delphi ja nicht, dass es ein Button ist und du kannst die speziellen Eigenschaften und Methoden eines Buttons nicht benutzen.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 30.11.08 15:30 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
if Sender is TButton then
  (Sender as TButton).Caption := 'geklickt'

Hier ist der 'as' Operator überflüssig bzw. zu viel des Guten, dann 'Sender' IST ja auf jeden Fall ein 'TButton'. Hier reicht ein einfaches Typecasting, denn 'as' ist eine relativ komplexe Operation mit Overhead. Hier reicht also (aber *nur* wegen der Prüfung mittels 'is'):
ausblenden Delphi-Quelltext
1:
2:
if Sender is TButton then
  TButton(Sender).Caption := 'geklickt'

_________________
Na denn, dann. Bis dann, denn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 15:33 
Nachdem ich vorher as gerade benutzt hatte wollte ich dort nicht gleich was anderes benutzen, das habe ich dann beim nächsten Mal ja gemacht ;-).
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 30.11.08 15:42 
Stimmt. :zustimm: Wollte halt auch mal was sagen...

_________________
Na denn, dann. Bis dann, denn.
Mitmischer 1703 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 15:59 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

user profile iconMitmischer 1703 hat folgendes geschrieben Zum zitierten Posting springen:
Die Sache mit dem as-Operator versteh ich aber nicht ganz... Nimmt man damit eine Typverwandlung vor. Also: Tu so als ob Sender gleich TButton wäre und führe dann >>bla, bla<< aus - Und bla, bla ist spezielle Funktion von TButton?!:?:?:?
Richtig, der in einer allgemeinen Variable z.B. vom Typ TObject gespeichert ist, soll wieder als TButton behandelt werden, denn wenn du die Variable ohne Typecast benutzt, dann weiß Delphi ja nicht, dass es ein Button ist und du kannst die speziellen Eigenschaften und Methoden eines Buttons nicht benutzen.

Und wenn Sender KEIN Button ist und wir die Prüfung mit is nicht da wäre, was passiert dann?

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 16:04 
Dann gibt es bei einem harten Typecast TButton(Sender) vermutlich eine Zugriffsverletzung und bei Verwendung des as-Operators (Sender as TButton) eine Exception (und deshalb eine Fehlermeldung) EInvalidTypecast oder so, dass die Typumwandlung nicht möglich ist.
Mitmischer 1703 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 16:07 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Dann gibt es bei einem harten Typecast TButton(Sender) vermutlich eine Zugriffsverletzung und bei Verwendung des as-Operators (Sender as TButton) eine Exception (und deshalb eine Fehlermeldung) EInvalidTypecast oder so, dass die Typumwandlung nicht möglich ist.

:shock: Und wofür braucht man as, wenn man doch is oder TEdit(Sender) hat?!

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 16:25 
Nun ja, wenn du as benutzt ohne vorher mit is zu prüfen, dann kommt im Fehlerfalle eine entsprechende aussagekräftige Fehlermeldung, wie gesagt. Wenn man sich sicher ist, dass der Typecast erfolgreich ist, z.B. weil man es mit is überprüft hat, dann kann man natürlich auch direkt casten mit TButton(Sender).
Problematisch ist dann nur, wenn doch ein falscher Cast passiert, denn dann kommt bei TButton(Sender) eine erstmal nichtsagende Zugriffsverletzung.
Mitmischer 1703 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 16:50 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Nun ja, wenn du as benutzt ohne vorher mit is zu prüfen, dann kommt im Fehlerfalle eine entsprechende aussagekräftige Fehlermeldung, wie gesagt. Wenn man sich sicher ist, dass der Typecast erfolgreich ist, z.B. weil man es mit is überprüft hat, dann kann man natürlich auch direkt casten mit TButton(Sender).
Problematisch ist dann nur, wenn doch ein falscher Cast passiert, denn dann kommt bei TButton(Sender) eine erstmal nichtsagende Zugriffsverletzung.


Ah, ok!

Und wie prüft man mit is, wenn man nicht den Typ sondern den Namen oder sonst etwas prüfen will. So?

ausblenden Delphi-Quelltext
1:
if Button1.Name is "Bla"					


Wie wird denn dann auf dei "Vorgänger" geprüft?!

_________________
Die Lösung ist nicht siebzehn.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.08 16:57 
Bei button1 kennst du ja den Typ, es geht ja um Sender oder andere Variablen, die einen allgemeineren Typ haben als den um den es geht. Wenn du den Namen prüfen willst, dann gehst du ja davon aus, dass es sich um eine Komponente handelt, also musst du darauf prüfen und kannst dann das Objekt als TComponent behandeln. In TComponent ist u.a. die Eigenschaft Name deklariert.
ausblenden Delphi-Quelltext
1:
2:
  if Sender is TComponent then
    ShowMessage(TComponent(Sender).Name);
Mitmischer 1703 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: So 30.11.08 16:59 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Bei button1 kennst du ja den Typ, es geht ja um Sender oder andere Variablen, die einen allgemeineren Typ haben als den um den es geht. Wenn du den Namen prüfen willst, dann gehst du ja davon aus, dass es sich um eine Komponente handelt, also musst du darauf prüfen und kannst dann das Objekt als TComponent behandeln. In TComponent ist u.a. die Eigenschaft Name deklariert.
ausblenden Delphi-Quelltext
1:
2:
  if Sender is TComponent then
    ShowMessage(TComponent(Sender).Name);

Ok! Danke!!!

_________________
Die Lösung ist nicht siebzehn.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 30.11.08 21:10 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Dann gibt es bei einem harten Typecast TButton(Sender) vermutlich eine Zugriffsverletzung

TButton(Sender).Visible würde wohl noch knapp gut gehen, auch wenn Sender ein TEdit wäre, solange Visible bei einem gleichen Vorfahren definiert ist. Aber das ist absolut schlecht und nicht zu empfehlen. Man sollte nie direkt casten, wenn der entsprechende Cast per as fehlschlagen könnte. Es gibt da einige ganz wenige Stellen im VCL Code, wo dies nicht gilt, aber zu empfehlen ist das so oder so nicht.
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2562
Erhaltene Danke: 46

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Mo 01.12.08 19:44 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
TButton(Sender).Visible würde wohl noch knapp gut gehen, auch wenn Sender ein TEdit wäre, solange Visible bei einem gleichen Vorfahren definiert ist. Aber das ist absolut schlecht und nicht zu empfehlen. Man sollte nie direkt casten, wenn der entsprechende Cast per as fehlschlagen könnte. Es gibt da einige ganz wenige Stellen im VCL Code, wo dies nicht gilt, aber zu empfehlen ist das so oder so nicht.

Um bei obigem Beispiel zu bleiben:
Ich mache das - TButton(Sender) - eigentlich immer dann so, wenn es definitiv immer nur ein TButton sein kann. Wenn mehrere Komponenten-Typen als Sender in Frage kommen, ist mir klar, dass man das berücksichtigen sollte, damit's nicht irgendwann kracht.

Aber Sender as verwende ich nicht (mehr).

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!