Нужны ли GUID для использования интерфейсов в Delphi? - PullRequest
19 голосов
/ 07 июня 2010

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

Ответы [ 2 ]

19 голосов
/ 07 июня 2010

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

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

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

Вот некоторая интересная информация об интерфейсах , которая гласит:

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

В обоих кавычках добавлено выделение.

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

7 голосов
/ 07 июня 2010

Только если вам нужно, чтобы ваш интерфейс был совместимым с 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;
...