słowo as i rzutowanie

0

czy zapis

TEdit( Sender ).Text := 'Delphi';

i

( Sender as TEdit ).Text := 'Delphi';

można stosować zamiennie?

2

nie do końca - as sprawdza czy typy się zgadzają natomiast () nie sprawdza - poczytaj o is

0

@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.

0
abrakadaber napisał(a)

nie do końca - as sprawdza czy typy się zgadzają natomiast () nie sprawdza - poczytaj o is

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 ListBoxem, 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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1