如何将对象列表传递给函数,该函数需要实现接口的对象列表?

Posted

技术标签:

【中文标题】如何将对象列表传递给函数,该函数需要实现接口的对象列表?【英文标题】:How to pass a list of objects to a function, which expects a list of objects which implement an interface? 【发布时间】:2021-12-08 17:23:41 【问题描述】:

tl;博士:

试图将对象列表传递给函数,该函数需要实现接口的对象列表。所述对象实现该接口。编译器不允许这样做。

寻找替代解决方法或我的错误。

设置

我没有使用实际代码,这在 IMO 中应该没有关系。对我来说似乎是一个概念问题。

TObjectWithInterface 类实现了ISomeInterface 接口并扩展了TCustomInterfacedObject 类,该类仅围绕IInterface 的引用计数工作,如documentation 中给出的那样。

TObjectWithInterface = class(TCustomInterfacedObject, ISomeInterface)

如果有一个过程接受实现该接口的对象列表:

procedure SomeFunction(List: TList<ISomeInterface>)

问题

TObjectWithInterface 的函数内部,我尝试使用TObjectWithInterface 的对象列表调用该函数:

procedure TObjectWithInterface.DoTheStuff(ListOfObjects: TList<TObjectWithInterface>)
begin
  // ...
  SomeFunction(ListOfObjects); // <-- Compiler error: Incompatible types
  // ...  
end;

编译器告诉我以下内容:

E2010:不兼容的类型:“System.Generics.Collections.TList”和“System.Generics.Collections.TList”

愚蠢的解决方法

我真的不喜欢我目前的解决方法,它包括创建一个新列表并将每个TObjectWithInterface 类型转换为ISomeInterface

procedure TObjectWithInterface.DoTheStuff(ListOfObjects: TList<TObjectWithInterface>)
var
  ListOfInterfaceObjects: TList<ISomeInterface>;
begin
  // ...
  ListOfInterfaceObjects := TList<ISomeInterface>.Create;
  for var Object in ListOfObjects do
    ListOfInterfaceObjects.Add(Objects as ISomeInterface);
  SomeFunction(ListOfInterfaceObjects)
  // ...  
end;

这对我来说似乎很 hacky。我可能做了一些愚蠢的事情,或者没有正确理解某些事情,因为这是我第一次尝试在 Delphi 中使用接口。请不要生气。

无论哪种方式,我希望有人能指出我的错误,或者,如果这是语言限制,有其他解决方法。

【问题讨论】:

【参考方案1】:

将对象列表复制到单独的接口列表中的“解决方法”实际上是正确且正确的解决方案。您不能在需要 TList&lt;Y&gt; 的地方使用 TList&lt;X&gt;,它们是不同且不相关的类型。仅仅因为您在接口上禁用引用计数并不会更改对象相对于其接口的内存布局,因此您仍然必须传递正确的内存指针,这意味着执行从一个到另一个的必要转换。

【讨论】:

以上是关于如何将对象列表传递给函数,该函数需要实现接口的对象列表?的主要内容,如果未能解决你的问题,请参考以下文章

将对象数组从 Ajax 函数传递到 Web 服务

如何将变量从 .map() 传递给回调函数

如何将指针分配给函数中的新对象,而该对象在退出后不会消失[重复]

如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?

将道具传递给散布在对象内的函数

如何将对象列表从 C++ 传递到 C#?