nor*_*aul 8 delphi generics interface delphi-xe7
我编写了一个接受类类型(T)和接口类型(I)的函数,并将一个接口(I)返回给对象(T).这是代码.
interface
function CreateObjectInterface<T: Class, constructor; I: IInterface>(
out AObject: TObject): I;
Run Code Online (Sandbox Code Playgroud)
...
implementation
function TORM.CreateObjectInterface<T, I>(out AObject: TObject): I;
begin
AObject := T.Create;
if not Supports(AObject, GetTypeData(TypeInfo(I))^.Guid, Result) then
begin
AObject.Free;
AObject := nil;
raise EORMUnsupportedInterface.CreateFmt(
'Object class "%s" does not support interface "%s"',
[AObject.ClassName, GUIDToString(GetTypeData(TypeInfo(I))^.GUID)]
);
end;
end;
Run Code Online (Sandbox Code Playgroud)
该功能按预期工作,没有内存泄漏或其他不受欢迎的问题.
还有其他方法可以达到相同的效果吗?
Ste*_*nke 14
这段代码中有一个错误.支持将破坏您的对象实例,如果它支持IUnknown但不支持您要求的接口.
简单演示:
type
IFoo = interface
['{32D3BE83-61A0-4227-BA48-2376C29F5F54}']
end;
var
o: TObject;
i: IFoo;
begin
i := TORM.CreateObjectInterface<TInterfacedObject, IFoo>(o); // <- boom, invalid pointer
end.
Run Code Online (Sandbox Code Playgroud)
最好放IInterface或IUnknown作为附加约束T.
或者确保您没有销毁已经被破坏的实例.
除非你想支持动态QueryInterface实现(类没有实现接口但QueryInterface返回它),我会Supports在类上调用:
function TORM.CreateObjectInterface<T, I>(out AObject: TObject): I;
begin
if not Supports(TClass(T), GetTypeData(TypeInfo(I))^.Guid) then
raise EORMUnsupportedInterface.CreateFmt(
'Object class "%s" does not support interface "%s"',
[AObject.ClassName, GUIDToString(GetTypeData(TypeInfo(I))^.GUID)]
);
AObject := T.Create;
Supports(AObject, GetTypeData(TypeInfo(I))^.Guid, Result);
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
493 次 |
| 最近记录: |