我有这样的设置:
IBuilder = interface(IInvokable)
end;
IBuilder<T: IBuilder; TOut : TWinControl> = interface(IInvokable)
end;
TBuilder<T: IBuilder; TOut : TWinControl> = class(TInterfacedObject, IBuilder, IBuilder<T, TOut>)
end;
TBuilder = class(TBuilder<TBuilder, TWinControl>)
end;
这种结构允许我构建如下糖语法:
TBuilder<T : IBuilder; TOut : TWinControl> = class(TInterfacedObject, IBuilder, IBuilder<T, TOut>)
function Output : TOut;
function Name(aName : string) : T;
function Left(aLeft : Integer) : T;
function Top(aTop : Integer) : T;
end;
// ... later
TBuilder.Create().Left(10).Top(5).Name('ABC'); // Nice one liner
问题是我收到编译错误,说
E2514 The type parameter TBuilder must support interface 'IBuilder'.
这可能是由于类型约束造成的T: IBuilder
存在于界面上,即使 TBuilder 确实支持 IBuilder(通过它的祖先)。
谁能指导我如何解决这个问题?
虽然,我不能使用TBuilder = class(TBuilder<IBuilder, TObject>)
这是不可能的。你本质上是想这样做:
IBar = interface(IInterface) end;
TFoo<T : IBar> = class(TObject, IBar) end;
TBar = TFoo<TBar>;
哪个会产生错误
E2086 类型“TBar”尚未完全定义
如果没有接口依赖性,您可以将其写为
TBar = class(TFoo<TBar>) end;
使其成为真正的后代,而不仅仅是一个别名。这通常可以解析类型,但接口依赖性迫使编译器提出以下问题:Does TBar
支持IBar
?
如果您考虑一下,结果如下:
TBar = TFoo<TBar> {TBar support IBar?}
|
TBar = TFoo<TBar>... {ok, TBar support IBar?}
|
TBar = TFoo<TBar> {ok, TBar support IBar?}
|
{...turtles all the way down}
您要求编译器解决无限递归问题。它不能这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)