Почему компилятор Delphi не видит, что я пытаюсь освободить интерфейс? - PullRequest
5 голосов
/ 01 ноября 2011

Я сделал небольшую ошибку при кодировании этого уик-энда.
В следующем коде я создаю объект и преобразую его в интерфейс . Позже я пытаюсь освободить его с FreeAndNil();

type
  IMyIntf = interface
     [...]
  end;

  TMyClass = class(TInterfacedObject, IMyIntf)
     [...]
  end;

var
  Myintf : IMyIntf;
begin
  Myintf := TMyClass.Create;
  [...] // Some process
  FreeAndNil(Myintf); // CRASH !!!
end;

Конечно, сбой программы на этой линии. Я полностью понимаю проблему , но я не понимаю, , почему компилятор не предупреждает меня об этом ? За этим нет динамических вещей, просто я пытаюсь освободить интерфейс !!! Почему бы мне не написать ошибку / предупреждение?

Есть ли какое-то реальное объяснение или это просто ограничение компилятора?

1 Ответ

10 голосов
/ 01 ноября 2011

Как вы знаете, правильный способ сделать это - написать Myintf := nil или просто вывести его из области видимости. Вы спрашиваете, почему компилятор принимает FreeAndNil(Myintf) и не жалуется во время компиляции.

Декларация FreeAndNil равна

procedure FreeAndNil(var Obj);

Это нетипизированный параметр. Следовательно, он примет все. Вы передали интерфейс, но вы могли передать целое число, строку и т. Д.

Почему дизайнеры выбрали нетипизированный параметр? Ну, им нужно было использовать параметр var, поскольку цель FreeAndNil состоит в том, чтобы освободить объект и установить ссылку на объект на nil. Это невозможно сделать методом целевого объекта, поэтому необходим параметр var для отдельной функции.

Вы можете себе представить, что можете написать

procedure FreeAndNil(var Obj: TObject);

, поскольку все объекты произошли от TObject. Но это не делает работу. Причина в том, что объект, который вы передаете параметрам var, должен быть точно таким же типом этого параметра. Если бы FreeAndNil было объявлено таким образом, вам пришлось бы приводить к TObject каждый раз, когда вы его вызывали.

Итак, дизайнеры решили, что лучшее решение проблемы проектирования, наименее плохой выбор, это использовать нетипизированный параметр var.

...