Подтвердить что ты не робот

Нужны ли GUID для использования интерфейсов в Delphi?

В официальной документации говорится, что они являются необязательными. Я знаю, что COM-взаимодействие требует уникального идентификатора для каждого интерфейса, но каждый пример интерфейса, который я вижу, имеет идентификатор GUID, независимо от того, использовался ли он с COM или нет? Есть ли какая-либо польза от включения GUID, если он не будет использоваться с COM?

4b9b3361

Ответ 1

Я заметил, что некоторые методы, такие как Supports (чтобы определить, соответствует ли класс определенному интерфейсу), требуют, чтобы вы определяли GUID, прежде чем вы сможете их использовать.

Эта страница подтверждает ее со следующей информацией:

Примечание. Блок SysUtils предоставляет перегруженная функция под названием Supports который возвращает true или false, когда класс типы и экземпляры поддерживают конкретный интерфейс, представленный GUID. Функция Supports используется в манере Дельфы есть и как операторы. Значительная разница заключается в том, что функция Supports может принимать как правый операнд либо GUID, либо тип интерфейса, связанный с GUID, тогда как есть и как следует назвать типа. Для получения дополнительной информации о is и as, см. Ссылки на классы.

Здесь некоторая интересная информация о интерфейсах, в которой говорится:

Почему интерфейс должен быть однозначно идентифицировать? Ответ просто: поскольку классы Delphi могут реализовать несколько интерфейсов. Когда приложение работает, быть механизмом, который получит указатель к соответствующему интерфейсу из реализация. Единственный способ найти если объект реализует интерфейс и получить указатель на реализация этого интерфейса через GUID.

Акцент добавлен в оба кавычки.

Чтение всей этой статьи также заставляет вас понять, что QueryInterface (который требует GUID) используется за кулисами по таким причинам, как ссылка считая.

Ответ 2

Только если вам нужен ваш интерфейс совместимый с COM.

К сожалению, это также включает в себя использование операторов is, as и QueryInterface, Supports функций, отсутствие которых является довольно ограничивающим. Таким образом, хотя это не требуется строго, возможно, проще использовать GUID. В противном случае вы остаетесь с довольно упрощенным использованием:

type
  ITest = interface
    procedure Test;
  end;

  ITest2 = interface(ITest)
    procedure Test2;
  end;

  TTest = class(TInterfacedObject, ITest, ITest2)
  public
    procedure Test;
    procedure Test2;
  end;

procedure TTest.Test;
begin
  Writeln('Test');
end;

procedure TTest.Test2;
begin
  Writeln('Test2');
end;

procedure DoTest(const Test: ITest);
begin
  Test.Test;
end;

procedure DoTest2(const Test: ITest2);
begin
  Test.Test;
  Test.Test2;
end;

procedure Main;
var
  Test: ITest;
  Test2: ITest2;
begin
  Test := TTest.Create;
  DoTest(Test);
  Test := nil;

  Test2 := TTest.Create;
  DoTest(Test2);
  DoTest2(Test2);
end;