用于定义泛型类正在实现的接口的通用参数

时间:2016-05-24 08:53:42

标签: delphi delphi-xe4

是否可以使用通用参数来定义类正在实现的接口? 或者有没有人有解释,为什么德尔福不允许这样做(或者我只是做错了?):

TInterfacedMyWrapper<T: IInterface> = class(TMyWrapper, T)
    function PropGetIntf(): T;
    property Intf: T read PropGetIntf implements T;
end;

这会产生以下错误:

  • E2205: Interface type required
  • E2259: Implements clause only allowed for properties of class or interface type

这是我的解决方法:

TInterfacedMyWrapper<T: IInterface> = class(TMyWrapper)
    function PropGetIntf(): T;
    property Intf: T read PropGetIntf;
end;

TIFooMyWrapper = class(TInterfacedMyWrapper<IFoo>, IFoo)
    property Intf: IFoo read PropGetIntf implements IFoo;
end;

但是这迫使我为每个接口定义一个单独的类。我更愿意写:

TInterfacedMyWrapper<IFoo>.Create(CompToWrap);



已编辑(更多上下文来解释我的目标 - 我希望它不会太混乱......):

我有多个派生自TFooComp的类,无法修改。我有一个包装类TMyWrapper,它继承自TBarBase。我无法修改TBarBaseTMyWrapperTFooComp(适配器模式)的包装器。

每个TFooComp派生类都可能暴露一个接口。我想要达到的是,TInterfacedMyWrapper也暴露了该接口(并将其委托给了 包裹TFooComp)。

这是以某种方式工作:

constructor TMyWrapper.CreateNew(AOwner: TComponent; FooClass: TFooClass);
begin
    FWrappedFooComp := FooClass.Create(Self);
    //...
end;

//...

function TInterfacedMyWrapper<T>.PropGetIntf(): T;
begin
    //see http://stackoverflow.com/questions/4418278/use-of-supports-function-with-generic-interface-type
    if not Supports(FWrappedFooComp, GetTypeData(TypeInfo(T))^.Guid, Result) then
      raise Exception.Create('Interface not implemented');
end;

但对于每个TFooComp派生类,我必须创建一个自己的包装类(只有一个声明):

TWrappedFooXxx = class(TInterfacedMyWrapper<IXxx>, Ixxx)
    property Intf: IXxx read PropGetIntf implements IXxx;
end;

我可以使用以下方式:

Result := TWrappedFooXxx.CreateNew(Owner, TFooXxx);
Result.DoSomething();
(Result as IXxx).DoSomeMore();

创建自己的包装类的必要性是我试图避免的。我宁愿只写:

Result := TInterfacedMyWrapper<IXxx>.CreateNew(Owner, TFooXxx);
Result.DoSomething();
(Result as IXxx).DoSomeMore();

1 个答案:

答案 0 :(得分:1)

  

为什么德尔福不允许这样做?

因为这不是C ++模板。 Delphi中的编译器需要知道您的类正在实现的接口(尽管它是通用的)。但在这种情况下它不能,因为你正在尝试实现一个尚未知的接口。