Toon posts:

[delphi] sender direct als goed object meegeven ?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Probleem

ben met een programma bezig waarvan alle editboxen en dergelijke gecontroleerd dienen te worden. nu heb ik dat allemaal al wel goed werken met zit met het volgende probleem

als ik alle edit boxen wil controleren heb ik 60x bv "if sender = edit2 then tmpedit:=edit2;"
staan. maar hoe kan ik in 1 keer maken dat de sender direct als een edit box te gebruiken is.
bv sender.text:= 'bla' ;

of is dit iets wat niet makkelijk kan

bedoel onderstaande code

code:
1
2
3
4
5
6
7
8
procedure TForm1.EditChange(Sender: TObject);
var tmpedit: Tedit;
begin
  if sender = edit1 then tmpedit:= edit1;
  if sender = edit2 then tmpedit:=edit2;


  tmpedit.Text:='bla';

Verwijderd

Dat kan niet. Je kunt wel casten, bv:

code:
1
2
  If Sender is TEdit then 
    TEdit(Sender).Text := 'blaat';

[ Voor 13% gewijzigd door Verwijderd op 09-12-2004 19:42 ]


  • Cloud
  • Registratie: November 2001
  • Laatst online: 08-05 14:53

Cloud

FP ProMod

Ex-moderatie mobster

Ik snap je probleem niet helemaal, maar bedoel je misschien:
code:
1
2
3
4
procedure TForm1.EditChange(Sender: TObject);
var tmpedit: Tedit;
begin
  tmpedit := TEdit(Sender);

Volgens mij werkt dit wel :)

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Verwijderd

wolkje schreef op donderdag 09 december 2004 @ 19:42:
Ik snap je probleem niet helemaal, maar bedoel je misschien:
code:
1
2
3
4
procedure TForm1.EditChange(Sender: TObject);
var tmpedit: Tedit;
begin
  tmpedit := TEdit(Sender);

Volgens mij werkt dit wel :)
Komt op hetzelfde neer. Je cast de Sender naar een TEdit. Die hele tmpedit is daardoor overbodig geworden. Overigens is de manier waarop jij het doet niet aan te raden, als de Sender dan geen TEdit is, kun je de leukste AV's krijgen.

[ Voor 13% gewijzigd door Verwijderd op 09-12-2004 19:44 ]


  • Cloud
  • Registratie: November 2001
  • Laatst online: 08-05 14:53

Cloud

FP ProMod

Ex-moderatie mobster

Verwijderd schreef op donderdag 09 december 2004 @ 19:43:
[...]


Komt op hetzelfde neer. Je cast de Sender naar een TEdit. Die hele tmpedit is daardoor overbodig geworden. Overigens is de manier waarop jij het doet niet aan te raden, als de Sender dan geen TEdit is, kun je de leukste AV's krijgen.
Dat is inderdaad waar ;) Beter zou zijn (in mijn stuk code):
code:
1
2
3
4
5
6
7
8
procedure TForm1.EditChange(Sender: TObject);
var tmpedit: Tedit;
begin
  if (sender is TEdit) then
      tmpedit := TEdit(Sender);
  else
      DoeNiets();
end;
Ofzoiets :9 Maar inderdaad, tmpedit is overbodig geworden na die cast. Ik snapte de bedoelingen van de TS ook niet helemaal ;)
offtopic:
nu lijkt mijn code heel veel op de jouwe :P

[ Voor 2% gewijzigd door Cloud op 09-12-2004 19:48 . Reden: eigenlijk beetje hetzelfde ]

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 21:24

NMe

Quia Ego Sic Dico.

Ik heb altijd leren casten op deze manier:
Delphi:
1
2
  If Sender is TEdit then 
    (Sender as TEdit).Text := 'blaat';

Is er een functioneel verschil? Ik vind er zo snel niets over terug.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Cloud
  • Registratie: November 2001
  • Laatst online: 08-05 14:53

Cloud

FP ProMod

Ex-moderatie mobster

Ik kan er zo niets over terugvinden in mijn delphi boek, maar dat zal ongetwijfeld kunnen. Het keyword as is wel meer in de stijl van is als je begrijpt wat ik bedoel ;) Maar functionele verschillen zou ik zo niet weten, ik heb as nooit gebruikt.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Verwijderd

Dit zegt mijn boek er over:
You can accomplish this by writing the following code:
code:
1
MyDog=TDog(MyAnmimal)

The same operation can be accomplished directly by the second RTTI operator, as, which converts the object only if the requested class is compatible with the actual one. The parameters of the as operator are an object and a class type, and the result is an object converted to the new class type.

The difference between the traditional cast and the use of the as cast is that the second raises an exception if the type if the object is incompatible with the type you are trying to cast it too.
bron: Mastering Delphi 6, Marco Cantu
Oftewel.. met de TEdit(edit1) cast wordt er niet gecontroleerd of die cast uberhaupt mogelijk is. Je kunt dan verderop in je code AV's krijgen als je properties aanspreekt die er niet zijn. Met de edit1 as TEdit cast wordt er gelijk gecontroleerd of die cast kan, en krijg je dan al je AV. De laatste is dus makkelijker te debuggen..

[ Voor 3% gewijzigd door Verwijderd op 09-12-2004 20:37 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

Maar aangezien je met is al checkt of het een TEdit is kan je net zo goed de directe cast gebruiken i.p.v. de cast.

Delphi:
1
2
3
4
if blaat is TEdit then
  Tedit(blaat).text = 'iets'
else
   ietsanders()


of
Delphi:
1
2
3
4
5
try
  (blaat as TEdit).text = 'iets';
except
  showmessage('blaat is geen Tedit!');
end;

Maar om nou te zeggen dat de as operator makkelijker is te debuggen dan een if :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Creepy schreef op donderdag 09 december 2004 @ 20:47:
Maar aangezien je met is al checkt of het een TEdit is kan je net zo goed de directe cast gebruiken i.p.v. de cast.
Uiteraard.. Je wil echter niet weten hoe vaak men die if weglaat, en in dat geval is een 'as' makkelijker te debuggen.

Als jij bv. in een groot project ergens
code:
1
tmpedit.text:='blaat';


ziet staan, zie je niet gelijk waarom je daar een exception op krijgt.

Verwijderd

-NMe- schreef op donderdag 09 december 2004 @ 20:06:
Ik heb altijd leren casten op deze manier:
Delphi:
1
2
  If Sender is TEdit then 
    (Sender as TEdit).Text := 'blaat';

Is er een functioneel verschil? Ik vind er zo snel niets over terug.
Mja.

De as operator probeert de cast uit te voeren en raiset een exception als deze mislukt. Dat is in principe nuttig, omdat je zeker weet dat verdere code die van de cast afhangt niet uitgevoerd wordt als deze niet geldig is (en daarmee access violations en whatever gaat veroorzaken), en aan de exception kun je zien wat er fout ging (namelijk de cast).

De is operator is een boolse functie die aangeeft of een cast zou lukken als die uitgevoerd zou worden door as. Hierop kun je dan case analysis uitvoeren, in plaats van exception handling.

In principe is een as na een is dus overbodig, omdat je al weet dat de cast toegestaan is. Je zou dus in principe net zo goed meteen `hard' kunnen casten. In de Delphi documentatie staat zelfs dat de constructie:

Delphi:
1
if Sender is TEdit then TEdit(Sender).{ ... };

efficiënter is dan
Delphi:
1
(Sender as TEdit).{ ... };


Ik heb alleen geen quantitatieve informatie over het verschil in efficiëntie.

Persoonlijk vind ik de laatste vorm wel weer mooier (duidelijker te lezen). Voor mensen die niet van exceptions houden (imagine that :p) is echter de eerste aan te raden.

Het idioom dat ik altijd (regelmatig toch) gebruik, is:

Delphi:
1
2
3
4
5
6
7
8
function TMyForm.MyEventHandler(Sender : Object);
begin
  with (Sender as TSpecificControl) do
  begin
    Caption := { ... };
    { ... };
  end;
end;

[ Voor 13% gewijzigd door Verwijderd op 10-12-2004 00:01 ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Verwijderd schreef op donderdag 09 december 2004 @ 23:59:
[...]
In principe is een as na een is dus overbodig, omdat je al weet dat de cast toegestaan is. Je zou dus in principe net zo goed meteen `hard' kunnen casten. In de Delphi documentatie staat zelfs dat de constructie:

Delphi:
1
if Sender is TEdit then TEdit(Sender).{ ... };

efficiënter is dan
Delphi:
1
(Sender as TEdit).{ ... };


Ik heb alleen geen quantitatieve informatie over het verschil in efficiëntie.
Dat verschil in efficiëntie verbaast me. De typecast TEdit(Sender) in het eerste voorbeeld kost geen rekentijd, want het is een operatie die de compiler uitvoert. De jump die uit de if-statement voortvloeit is ook verwaarloosbaar.

Zowel de is als de as operator maakt gebruik van RTTI (runtime type information). Het efficiëntieverschil moet hem bij gebrek aan andere verklaringen wel zitten in de manier waarop beide operatoren met de RTTI omgaan. In beide gevallen moet worden gecontroleerd of Sender een instantie is van een class die van TEdit afstamt, ik zie dus geen verschil.

Ik maak bij de gegeven constructies trouwens liever gebruik van de base class van een object, dat maakt de code net iets generieker (al maakt het in de meeste gevallen niets uit). Het is gewoon een kwestie van voorkeur.
Delphi:
1
with Lijstje as TStringList do ...

wordt bij mij dus meestal
Delphi:
1
with Lijstje as TStrings do ...

Als ik dan ooit nog op een idee kom om een Lijstje van het type TMyStrings (een zelfgemaakte descendant van TStrings) te gebruiken, werkt mijn code tenminste nog.

Een goede grap mag vrienden kosten.

Pagina: 1