czy zapis
TEdit( Sender ).Text := 'Delphi';
i
( Sender as TEdit ).Text := 'Delphi';
można stosować zamiennie?
czy zapis
TEdit( Sender ).Text := 'Delphi';
i
( Sender as TEdit ).Text := 'Delphi';
można stosować zamiennie?
nie do końca - as
sprawdza czy typy się zgadzają natomiast ()
nie sprawdza - poczytaj o is
@abrakadaber podał prawidłową odpowiedź. Jednak nie zawsze można stosować takie rzutowanie zamiennie. Nie można tego robić w przypadku zabaw z interfejsami, ponieważ adres interfejsu jest inny niż adres obiektu. Np. taki kod:
IInterface1 = interface
['{710C510E-FA28-4CFD-B194-6D9BA7A0CE0B}']
procedure Method1;
end;
IInterface2 = interface
['{320FFF59-0C83-4E89-AFBA-054DED84572E}']
procedure Method2;
end;
TImplementation = class(TInterfacedObject, IUnknown, IInterface1, IInterface2)
strict private
F1, F2: Double;
public
constructor Create;
procedure Method1;
procedure Method2;
end;
....
constructor TImplementation.Create;
begin
F1 := 1.0;
F2 := -1.0;
end;
procedure TImplementation.Method1;
begin
dbg(F1);
end;
procedure TImplementation.Method2;
begin
dbg(F2);
end;
....
var
Variable: IInterface1;
begin
Variable := TImplementation.Create as IInterface1;
Variable.Method1;
IInterface2(Variable).Method2;
end;
się skompiluje, jednak jest błędny. W obu przypadkach do dbg trafi 1
. W przypadku typów obiektowych, a szczególnie interfejsów radzę używać tylko rzutowania bezpiecznego - z wykorzystaniem as
. Tak naprawdę tutaj w obu przypadkach zostanie wykonana metoda Method1
, ale w innych sytuacjach skutki mogą być gorsze.
abrakadaber napisał(a)
nie do końca -
as
sprawdza czy typy się zgadzają natomiast()
nie sprawdza - poczytaj ois
Warto także wspomnieć, że jeśli ma się stuprocentową pewność co do klasy danego obiektu, to wtedy można wykorzystać bezpośrednie rzutowanie; Ten wariant bardzo często stosuję podczas rysowania po Canvas
w ListBox.DrawItem
:
with TListBox(Control).Canvas do
begin
// instrukcje rysujące
end;
po to, by związać blok with .. do
z kanwą kontrolki i uwolnić się od ciągłego rzutowania podczas rysowania, lub wykluczyć deklarowanie dodatkowej zmiennej, do której przypisany byłby "przekonwertowany" argument; W tym wypadku jednak mam pewność, że argument Control
zawsze będzie ListBox
em, więc mogę rzutować bezpośrednio;
Jednak operator as
daje możliwość wcześniejszego przetestowania rzutowania - jest to rodzaj zabezpieczenia; Poczytaj sobie więcej na temat operatora As i często idącego w parze operatora Is.