Delphi - сбориник статей


Фокус второй (With-trick)


Предположим у нас есть следующая функция:

procedure ShowText(sl: TStringList); begin ShowMessage(sl.text); end; Figure 16.

И кнопка на форме:

procedure TfrmAllMiracles.btnWithSelfTrickClick(Sender: TObject); var sl: TStringList; begin sl := TStringList.Create; try sl.CommaText := '1,2,3,4,5,6,7,8,9,0'; ShowText(sl); finally sl.Free; end; end; Figure 17.

И мы, по каким-то причинам, хотим избавиться от локальной переменной sl. Но для того, что бы обратиться к функции ShowText, мы должны передать ей параметр типа TStringList. Откуда же его взять?

Давайте порассуждаем. Каждый метод получает скрытый параметр Self, может быть как-то можно вытащить его оттуда? Писать для этого специальный метод какого-то класса не хотелось бы - ведь это работало бы только для его потомков.

Давайте почитаем Help, раздел "TMethod type":
...This type can be used in a type cast of a method pointer to access the code and data parts of the method pointer... Не это ли то, что мы ищем?
Определим тип и функцию:

type TSimpleMethod = procedure of object; function GetWithSelf(const pr: TSimpleMethod): TObject; begin Result := TMethod(pr).Data; end; Figure 18.

Как видите, функция принимает указатель на метод, а возвращает обьект, являющийся владельцем этого метода. Но каким же методом мы воспользуемся? Например, метод Free, ведь его история восходит еще к самому TObject'у. Теперь проверим себя:

procedure TfrmAllMiracles.btnWithSelfTrickClick(Sender: TObject); begin with TStringList.Create do try CommaText := '1,2,3,4,5,6,7,8,9,0'; ShowText(TStringList(GetWithSelf(Free))); finally Free; end; end; Figure 19.

Проверьте - работает.

Автор —
Живет и работает в Израиле. Женат, имеет двоих детей.
Сфера интересов - Delphi, Windows, Oracle, GSM биллинг.




Начало  Назад