The official documentation says they are optional. I know COM interop requires a unique identifier for each interface but every interface example I see has a GUID whether it's used with COM or not? Is there any benefit to including a GUID if its not going to be used with COM?
Only if you need your interface to be compatible with COM.
Unfortunately, that also includes using is, as operators and QueryInterface, Supports functions - the lack of which is rather limiting. So, while not strictly required, it's probably easier to use a GUID. Otherwise, you are left with rather simplistic usage only:
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;
I've noticed that some methods such as Supports (to determine if a class conforms to a specific interface) require that you define a GUID before you can use them.
This page confirms it with the following information:
Note: The SysUtils unit provides an overloaded function called Supports that returns true or false when class types and instances support a particular interface represented by a GUID. The Supports function is used in the manner of the Delphi is and as operators. The significant difference is that the Supports function can take as the right operand either a GUID or an interface type associated with a GUID, whereas is and as take the name of a type. For more information about is and as, see Class References.
Here's some interesting information about interfaces, which states:
Why does an interface need to be uniquely identifiable? The answer is simple: because Delphi classes can implement multiple interfaces. When an application is running, there has to be a mechanism that will get pointer to an appropriate interface from an implementation. The only way to find out if an object implements an interface and to get a pointer to implementation of that interface is through GUIDs.
Emphasis added in both quotes.
Reading this entire article also makes you realize that QueryInterface (which requires a GUID) is used behind the scenes for reasons such as reference counting.