Официальная документация говорит, что они необязательны. Я знаю, что COM-взаимодействие требует уникального идентификатора для каждого интерфейса, но каждый пример интерфейса, который я вижу, имеет GUID независимо от того, используется ли он с COM или нет? Есть ли польза от включения GUID, если он не будет использоваться с COM?
Нужны ли идентификаторы GUID для использования интерфейсов в Delphi?
Ответы (2)
Я заметил, что некоторые методы, такие как Supports
(для определения соответствия класса к определенному интерфейсу) требуют, чтобы вы определили GUID, прежде чем вы сможете их использовать.
Эта страница подтверждает это следующей информацией:
Примечание. Модуль SysUtils предоставляет перегруженную функцию с именем Supports, которая возвращает значение true или false, когда типы и экземпляры классов поддерживают определенный интерфейс, представленный GUID. Функция Supports используется аналогично Delphi is and как операторы. Существенное отличие состоит в том, что функция Supports может принимать в качестве правильного операнда либо GUID, либо тип интерфейса, связанный с GUID, тогда как is и as принимают имя типа. Дополнительные сведения о is и as см. в разделе Ссылки на классы.
Вот интересная информация об интерфейсах, в которой говорится:
Почему интерфейс должен быть однозначно идентифицируемым? Ответ прост: потому что классы Delphi могут реализовывать несколько интерфейсов. Когда приложение работает, должен быть механизм, который получит указатель на соответствующий интерфейс из реализации. Единственный способ узнать, реализует ли объект интерфейс, и получить указатель на реализацию этого интерфейса — через идентификаторы GUID.
Выделение добавлено в обе цитаты.
Прочитав всю эту статью, вы также поймете, что QueryInterface
(для которого требуется GUID ) используется за кулисами по таким причинам, как подсчет ссылок.
is
или as
с интерфейсом включает в себя один из этих вызовов (не помню какой) под капотом, поэтому для этого вам также понадобится GUID.
- person Mason Wheeler; 07.06.2010
Supports
пока единственная причина, по которой я определяю GUID для интерфейсов.
- person Edwin Yip; 16.04.2012
Только если вам нужно, чтобы ваш интерфейс был совместим с 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;
IFoo
без отношения подтипа к ITest
. Как преобразовать ссылку ITest
в ссылку IFoo
, предполагая, что тип реализации поддерживает оба варианта. Вам нужен GUID, чтобы сделать это безопасно.
- person Craig Stuntz; 08.06.2010