| Autor |
Beitrag |
Mitmischer 1703
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 13:30
Wofür gibt es den Is-Operator?
Edit: Arrgh *drauf geh* Ich hab meinen 400.Post verpasst!  *schmoll*
_________________ Die Lösung ist nicht siebzehn.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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: 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: 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: Delphi-Quelltext
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 
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 15:06
Aber kann man nicht mit
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
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 30.11.08 15:24
Mitmischer 1703 hat folgendes geschrieben : | Aber kann man nicht mit
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: 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.
Mitmischer 1703 hat folgendes geschrieben : | 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
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: So 30.11.08 15:30
_________________ Na denn, dann. Bis dann, denn.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: So 30.11.08 15:42
Stimmt.  Wollte halt auch mal was sagen...
_________________ Na denn, dann. Bis dann, denn.
|
|
Mitmischer 1703 
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 15:59
_________________ Die Lösung ist nicht siebzehn.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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 
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 16:07
_________________ Die Lösung ist nicht siebzehn.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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 
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 16:50
jaenicke hat folgendes geschrieben : | 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?
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
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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.
Delphi-Quelltext 1: 2:
| if Sender is TComponent then ShowMessage(TComponent(Sender).Name); |
|
|
Mitmischer 1703 
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: So 30.11.08 16:59
_________________ Die Lösung ist nicht siebzehn.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 30.11.08 21:10
jaenicke hat folgendes geschrieben : | | 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
      
Beiträge: 2562
Erhaltene Danke: 46
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 01.12.08 19:44
delfiphan hat folgendes geschrieben : | | 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!
|
|
|