加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 使用Generics创建接口对象

发布时间:2020-12-15 03:55:25 所属栏目:大数据 来源:网络整理
导读:我编写了一个接受类类型(T)和接口类型(I)的函数,并将一个接口(I)返回给对象(T).这是代码. interfacefunction CreateObjectInterfaceT: Class,constructor; I: IInterface( out AObject: TObject): I; … implementationfunction TORM.CreateObjectInterfaceT
我编写了一个接受类类型(T)和接口类型(I)的函数,并将一个接口(I)返回给对象(T).这是代码.
interface

function CreateObjectInterface<T: Class,constructor; I: IInterface>(
  out AObject: TObject): I;

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;

该函数按预期工作,没有内存泄漏或其他不受欢迎的问题.

还有其他方法可以达到相同的效果吗?

解决方法

这段代码中有一个错误.如果支持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.

最好将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"',GUIDToString(GetTypeData(TypeInfo(I))^.GUID)]
    );

  AObject := T.Create;
  Supports(AObject,Result);
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读