如何获取在 Delphi 中作为通用参数传递的界面的 GUID?
How to obtain GUID of interface passed as a generic parameter in Delphi?
在下文中,方法 Obtain() 有效,但 GetAs() 方法对于调用者来说会更整洁。
但是,我不知道如何将接口作为通用参数传递并获取其 GUID。
声明:
TInterfaceRegistry = class
private
fRegistry: TDictionary<TGUID, IInterface>;
public
...
procedure Register(const IID: TGUID; IntfObj: IInterface; const Replace: Boolean = False);
function Obtain(const IID: TGUID; out IntfObj): Boolean;
function GetAs<I: IInterface>(): I;
end;
实施:
function TInterfaceRegistry.Obtain(const IID: TGUID; out IntfObj): Boolean;
var
Found: IInterface;
begin
Result := fRegistry.TryGetValue(IID, Found);
if Result then
if not Supports(Found, IID, IntfObj) then
raise EBatSoft.Create(SEBatSoftBug);
end;
function TInterfaceRegistry.GetAs<I>(): I;
begin
if not Obtain(I, Result) then
raise EBatSoft.Create(SEDoesNotImplement);
end;
调用它看起来像这样...
IntfReg.Register(IMyIntf, TMyImpl.Create);
正在实施:
var
Intf: IMyIntf;
begin
// Less type-safe (can pass anything into 2nd parameter)
if IntfReg.Obtain(IMyIntf, Intf) then
...
// Fully type-safe, and simple
Intf := IntfReg.GetAs<IMyIntf>();
您必须通过 GetTypeData(TypeInfo(I)).GUID
使用类型信息。
请记住,如果您没有为正在使用的给定接口声明任何内容,那么这可能 return 一个空的 GUID,而非通用方法根本无法编译。
在下文中,方法 Obtain() 有效,但 GetAs() 方法对于调用者来说会更整洁。
但是,我不知道如何将接口作为通用参数传递并获取其 GUID。
声明:
TInterfaceRegistry = class
private
fRegistry: TDictionary<TGUID, IInterface>;
public
...
procedure Register(const IID: TGUID; IntfObj: IInterface; const Replace: Boolean = False);
function Obtain(const IID: TGUID; out IntfObj): Boolean;
function GetAs<I: IInterface>(): I;
end;
实施:
function TInterfaceRegistry.Obtain(const IID: TGUID; out IntfObj): Boolean;
var
Found: IInterface;
begin
Result := fRegistry.TryGetValue(IID, Found);
if Result then
if not Supports(Found, IID, IntfObj) then
raise EBatSoft.Create(SEBatSoftBug);
end;
function TInterfaceRegistry.GetAs<I>(): I;
begin
if not Obtain(I, Result) then
raise EBatSoft.Create(SEDoesNotImplement);
end;
调用它看起来像这样...
IntfReg.Register(IMyIntf, TMyImpl.Create);
正在实施:
var
Intf: IMyIntf;
begin
// Less type-safe (can pass anything into 2nd parameter)
if IntfReg.Obtain(IMyIntf, Intf) then
...
// Fully type-safe, and simple
Intf := IntfReg.GetAs<IMyIntf>();
您必须通过 GetTypeData(TypeInfo(I)).GUID
使用类型信息。
请记住,如果您没有为正在使用的给定接口声明任何内容,那么这可能 return 一个空的 GUID,而非通用方法根本无法编译。