是否可以使用通用参数来定义类正在实现的接口? 或者有没有人有解释,为什么德尔福不允许这样做(或者我只是做错了?):
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
。我无法修改TBarBase
。
TMyWrapper
是TFooComp
(适配器模式)的包装器。
每个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();
答案 0 :(得分:1)
为什么德尔福不允许这样做?
因为这不是C ++模板。 Delphi中的编译器需要知道您的类正在实现的接口(尽管它是通用的)。但在这种情况下它不能,因为你正在尝试实现一个尚未知的接口。