Передача объекта в качестве интерфейса - PullRequest
4 голосов
/ 26 мая 2010

Это должен быть простой ответ, я считаю, что это будет нет,
но взяты из более крупного проекта, у меня есть интерфейс и процедура

iMyUnknown= interface(IInterface)
 ['..GUID..']
end;
procedure WorkObject(iObj :iMyUnknown);

я знаю, что это работает

var 
  MyUnknown : iMyUnknown;
begin
 if supports(obj, iMyUnknown, MyUnknown) then
  WorkObject(MyUnknown);

Но возможно ли сделать что-то подобное?

if supports(obj, iMyUnknown) then
  WorkObject(obj as iMyUnknown);

Ответы [ 3 ]

5 голосов
/ 26 мая 2010

Зачем вам разыгрывать?

Если obj поддерживает интерфейс, и все, что вам нужно сделать, это проверить, что перед передачей его в процедуру вы можете просто передать сам объект. Компилятор позаботится обо всем остальном. Третий параметр в вызове Supports нужен только для доступа к методам интерфейса.

Скомпилируйте и запустите код ниже. Он должен скомпилироваться без ошибок и предоставить вам окно консоли и диалоговое сообщение.

program Project1;

{$APPTYPE CONSOLE}

uses
  Classes
  , Dialogs
  , SysUtils
  ;

type
  iMyUnknown = interface(IInterface)
  ['{DA867EBA-8213-4A91-8E03-1AACA150CE77}']
    procedure DoSomething;
  end;

  TMuster = class(TInterfacedObject, iMyUnknown)
    procedure DoSomething;
  end;

procedure WorkObject(iObj: iMyUnknown);
begin
  if Assigned(iObj) then ShowMessage('Got something');
end;

{ TMuster }

procedure TMuster.DoSomething;
begin
  beep;
end;

var
  obj: TMuster;
begin
  try
    obj := TMuster.Create;
    if Supports(obj, iMyUnknown) then
      WorkObject(obj);
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
3 голосов
/ 26 мая 2010

Да, вы можете. Оператор as работал с интерфейсами с тех пор, как в язык была добавлена ​​поддержка интерфейсов (вокруг Delphi 3, IIRC). Отправленный вами код работает. Где проблема?

3 голосов
/ 26 мая 2010

Вы можете привести объект к интерфейсу с помощью as-cast, если компилятор знает, что ваш объект поддерживает IInterface, а ваш интерфейс имеет GUID. Так что он не будет работать с TObject, но с TInterfacedObject это будет работать.

...