В официальной документации говорится, что они являются необязательными. Я знаю, что COM-взаимодействие требует уникального идентификатора для каждого интерфейса, но каждый пример интерфейса, который я вижу, имеет идентификатор GUID, независимо от того, использовался ли он с COM или нет? Есть ли какая-либо польза от включения GUID, если он не будет использоваться с COM?
Нужны ли GUID для использования интерфейсов в Delphi?
Ответ 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;