delphi – 使用Generics创建接口对象

前端之家收集整理的这篇文章主要介绍了delphi – 使用Generics创建接口对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我编写了一个接受类类型(T)和接口类型(I)的函数,并将一个接口(I)返回给对象(T).这是代码.
  1. interface
  2.  
  3. function CreateObjectInterface<T: Class,constructor; I: IInterface>(
  4. out AObject: TObject): I;

  1. implementation
  2.  
  3. function TORM.CreateObjectInterface<T,I>(out AObject: TObject): I;
  4. begin
  5. AObject := T.Create;
  6.  
  7. if not Supports(AObject,GetTypeData(TypeInfo(I))^.Guid,Result) then
  8. begin
  9. AObject.Free;
  10. AObject := nil;
  11.  
  12. raise EORMUnsupportedInterface.CreateFmt(
  13. 'Object class "%s" does not support interface "%s"',[AObject.ClassName,GUIDToString(GetTypeData(TypeInfo(I))^.GUID)]
  14. );
  15. end;
  16. end;

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

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

解决方法

这段代码中有一个错误.如果支持IUnknown而不支持您要求的接口,则支持将销毁您的对象实例.

简单演示:

  1. type
  2. IFoo = interface
  3. ['{32D3BE83-61A0-4227-BA48-2376C29F5F54}']
  4. end;
  5.  
  6. var
  7. o: TObject;
  8. i: IFoo;
  9. begin
  10. i := TORM.CreateObjectInterface<TInterfacedObject,IFoo>(o); // <- boom,invalid pointer
  11. end.

最好将IInterface或IUnknown作为T的附加约束.

或者确保您没有销毁已经被破坏的实例.

除非你想支持动态QueryInterface实现(其中类没有实现接口但QueryInterface返回它),我会在类上使用Supports调用

  1. function TORM.CreateObjectInterface<T,I>(out AObject: TObject): I;
  2. begin
  3. if not Supports(TClass(T),GetTypeData(TypeInfo(I))^.Guid) then
  4. raise EORMUnsupportedInterface.CreateFmt(
  5. 'Object class "%s" does not support interface "%s"',GUIDToString(GetTypeData(TypeInfo(I))^.GUID)]
  6. );
  7.  
  8. AObject := T.Create;
  9. Supports(AObject,Result);
  10. end;

猜你在找的Delphi相关文章