Шаг 147.
Операции is и as

    На этом шаге мы рассмотрим операции is и as.


    Для работы с информацией о типах времени выполнения (RTTI) в Object Pascal введены две новые операции: is и as.

    Операция is является бинарной, то есть имеющей два операнда, и принимает следующий вид:

  <Объект> is <Класс>    .

    Она позволяет определить во время выполнения принадлежность Объекта указанному Классу или одному из его потомков. Результатом будет булевская величина, принимающая значение True, если объект совместим по присваиванию с классом Класс, и значение False - в противном случае. Операция is имеет низший приоритет наряду с операциями сравнения =, <>, <, >, <=, >= и операцией in, и поэтому в выражениях заключается в скобки вместе со своими операндами:

  if   (Sender  is TEdit)   or   (Sender  is TMemo)    then

    Одним из часто встречаемых случаев использования операции is является безопасное преобразование типов, для которого применяется конструкция такого вида:

  if <Объект> is <Класс> then <Класс>(<Объект>).<Метод>;

    Для демонстрации работы операции is приведем следующий пример.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    CheckBox1: TCheckBox;
    procedure CommonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CommonClick(Sender: TObject);
begin
  if Sender is TButton then
    Memo1.Lines.Add ('Щелчок на одной из кнопок') 
  else
    Memo1.Lines.Add ('Щелчок не на кнопках') 
end;

end.
Текст этого примера можно взять здесь.

    В этом примере показано выделение компонент-кнопок класса TButton из всего множества компонент формы в случае использования общего для этих кнопок обработчика события OnClick. Для корректной работы примера необходимо с помощью Object Inspector всем компонентам формы Form1 поставить в соответствие один и тот же обработчик события OnClick с идентификатором CommonClick. Если после запуска проекта на выполнение последовательно щелкнуть на форме Form1, поле Memo1, кнопках Button1, Button2, Button3 и контрольном поле CheckBox1, то получим следующий результат:


Рис.1. Результат работы приложения

    Операция as предназначена для преобразования типов, у нее так же, как и у операции is два операнда, и ее общий вид можно представить следующим образом:

  <Объект>  as  <Класс>      .

    Эта операция имеет второй приоритет наряду с операциями типа умножения: *, /, dlv, mod, and, shl и shr.

    Результатом операции as будет тот же самый объект, но уже принадлежащий не к своему первоначальному классу, а к указанному в операторе классу Класс.

    Главное отличие операции as от прямого преобразования типов вида:

  <Класс>(<Объект>)

состоит в том, что при обработке операции as во время выполнения происходит проверка корректности преобразования типов. Если Объект совместим по присваиванию с Классом, то преобразование выполняется. Если же не совместим, то возникает исключительная ситуация, для которой при необходимости можно написать свой обработчик. В случае прямого преобразования типов никаких проверок на совместимость не выполняется.

    Операция as используется для безопасного преобразования типов во время выполнения и практически эквивалентна вышеприведенной конструкции с использованием оператора is. Но, в отличие от нее, позволяет писать более компактный и наглядный код, если используется вместе с оператором with:

  with <Объект>  as  <Класс> do  

или прямо в квалифицируемом идентификаторе:

  (<Объект> as <Класс>).<Поле>
  (<Объект> as <Класс>).<Метод>

    Для демонстрации преобразования типов с помощью операции as возьмем пример, аналогичный вышеприведенному для операции is.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    CheckBox1: TCheckBox;
    procedure CommonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CommonClick(Sender: TObject);
begin
  Memo1.Lines.Add ('Щелчок на ' +(Sender as  TControl).Name)
end;

end.
Текст этого примера можно взять здесь.

    В методе TForm1.CommonClick, который выполняет обработку события OnClick для всех компонент формы Form1, происходит преобразование типа объекта-источника события (параметр Sender) к классовому типу TControl. Поскольку класс TControl является предком всех используемых в проекте компонент (Form1, Memo1, Button1, Button2, Button3, CheckBox1), то преобразование выполняется корректно. В результате, один и тот же оператор:

  Memo1.Lines.Add   ('Щелчок  на   ' + (Sender  as  TControl).Name);

выводит в поле Memo1 имена всех компонент, на которых выполняется щелчок мышью. На рисунке 2 показан результат работы проекта, если после его запуска на выполнение последовательно щелкнуть на форме Form1, поле Memo1, кнопках Button1, Button2, Button3 и флажке CheckBox1:


Рис.2. Результат работы приложения

    Мы закончили изложение материала по языку Object Pascal. Надеемся, что приведенный справочный материал поможет Вам при программировании в среде Delphi.




Предыдущий шаг Содержание