gpt4 book ai didi

delphi - 从接口(interface)获取子接口(interface)

转载 作者:行者123 更新时间:2023-12-03 14:37:32 26 4
gpt4 key购买 nike

这是接口(interface)的一种特殊情况,其中一个类实现同一接口(interface)的多个版本,即。类似下面的内容

IBase = interface
procedure Foo;
end;

ISub = interface (IBase)
procedure Bar;
end;

ISpecialBase = interface (IBase) end;

ISpecialSub = interface (ISub) end;

TMyClass = class(TInterfacedObject, ISpecialBase, ISpecialSub)

procedure SpecialFoo1;
procedure SpecialFoo2;
procedure SpecialBar;

procedure ISpecialBase.Foo = SpecialFoo1;

procedure ISpecialSub.Foo = SpecialFoo2;
procedure ISpecialSub.Bar = SpecialBar;

function GetTheRightOne(parameters) : IBase;

end;

...

function TMyClass.GetTheRightOne(parameters) : IBase;
begin
if (something complex depending on parameters) then
Result := ISpecialBase(Self)
else Result := ISpecialSub(Self)
end;

当然,真实情况下大约有十几个ISpecialXxxx。

有一个非常重要的需求,即只有一个实例。我想避免仅仅为了推迟 ISpecialXxxx 实现而创建适配器或虚拟实例,因为先前设计的唯一目的正是让单个实例处理许多未完成的接口(interface)(即 TMyClass 的 RefCount 可以达到千分之一) )。

现在的问题是 GetTheRightOne() 返回一个 IBase,但在某些时候我想检查该 IBase 是否可以转换为 ISub。

有没有办法用上面的申报表来做到这一点?

一种方法是添加一个

function GetSub : ISub;

到IBase,但这确实使设计变得更重,因为它必须为每个ISpecialXxxx实现,并且对于ISpecialXxxx“继承”来说是多余的,所以我正在寻找一个更优雅的解决方案(假设它存在)。

(我还有其他“膨胀”解决方案,所以我真的想强调我正在寻找一个非膨胀解决方案)

编辑:更多详细信息

  • 原始代码中存在 GUID(但缺少 GUID 并不是造成困难的原因)
  • Supports 和 QueryInterface 不起作用,因为 ISpecialXxx 需要每个类有多个版本的接口(interface),ISub 没有明确列出,因此找不到。然而,当使用适配器/虚拟类来延迟接口(interface)时,两者都有效(因为这样 ISub 可以显式列出)

edit2:如果你想要血淋淋的细节

检查https://code.google.com/p/dwscript/source/browse/trunk/Source/dwsJSONConnector.pas (r2492)、TdwsJSONConnectorType 类和 IJSONLow 接口(interface),目标是在作为 IConnectorCall 传递时从中检测到 IConnectorFastCall,从而能够调用 LowFastCall 而不是 LowCall。

检测必须发生在 TConnectorCallExpr.AssignConnectorSym,第 294 行,其中当前有一个 QueryInterface。

请注意,QueryInterface 在 TdwsJSONIndexReadCall 和 TdwsJSONIndexWriteCall 的情况下工作,因为它们从不同的类和实例实现 IConnectorCall 和 IConnectorFastCall。但这正是我想避免的。

当然,理想情况下,目标是将所有内容折叠到 ConnectorType 类中(单个类、单个实例),并且对于每个接口(interface),特定的 ConnectorType 类应该可以自由地实现 IConnectorCall 或 IConnectorFastCall。

最佳答案

要查看一个接口(interface)的实现者是否实现了另一个接口(interface),您可以使用 Supports或 QueryInterface,如以下伪代码所示:

var
Base: IBase;
Sub: ISub;
begin
Base := X.GetTheRightOne(Params);
if Supports(Base, ISub, Sub) then
Sub.Bar;
end;

编辑:要使上述工作正常进行,您需要将 IID 添加到接口(interface)的声明中。

关于delphi - 从接口(interface)获取子接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22840183/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com