【问题标题】:Container to store anonymous methods存储匿名方法的容器
【发布时间】:2011-10-13 08:45:06
【问题描述】:

我有以下定义。

type
  TOmniTaskDelegate = reference to procedure(const task: IOmniTask);

我应该使用什么类型的容器(应该在 D2009 中支持)来存储 TOmniTaskDelegate 实例列表?目前我正在使用array of TOmniTaskDelegate,但我对此并不满意。

【问题讨论】:

  • 你为什么对数组不满意?
  • a) 因为我想将责任委托给具有明确定义接口的容器,并且 b) 因为我现在每次向其添加内容时都会调整数组的大小。没错,我可以在数组周围编写一个很好的包装器,它会知道当前大小和分配的大小等,但是我已经在重新实现 TSomeList 并且我宁愿使用 Delphi 提供的东西(假设存在这样的东西) .
  • 什么是TSomeList<T>?你不能用TSomeList<TOmniTaskDelegate>吗?
  • TSomeList = TList、TObjectList 或 TIDontKnowWhatElseIsSupportedInD2009List

标签: delphi containers anonymous-methods


【解决方案1】:

我会使用TList<TOmniTaskDelegate>。由于使用泛型,这是类型安全的,因此它将正确处理其成员的生命周期问题。

【讨论】:

  • 我正在考虑 Generics.Collections 中的 TList<T>。这确实处理了引用计数,因为它是类型安全的。但是现在我有一个挥之不去的疑问,它可能不会包含在 D2009 中。
  • TObjectList 不是合适的容器,因为匿名方法引用需要包括对方法的引用以及对接口“自身”的引用。换句话说,大小将是 2 x SizeOf(Pointer)。
  • +1。显然,通用 TList<T> 在 Delphi 2009 中可用。无需重新发明轮子:通用列表是使用 array of 实现的,因此可以保证正确完成并确保类型安全。跨度>
  • @Heinrich 那是因为它是一个不同的参考。请记住,匿名方法具有变量捕获。
  • @David 多次添加相同的method of object 也会给出不同的引用。这让我第一次遇到它时感到很惊讶。我以为他们会是一样的。
【解决方案2】:

编辑:Delphi 2009 包含通用的TList<T>,我假设它是使用array of 实现的,就像在Delphi 2010 中一样。这使得TList<T> 成为最佳选择!我保留原来的答案是因为它解释了为什么array of 是一个很棒的数据结构以及为什么使用它会带来很多麻烦。


您选择的array of Anonym 对我来说非常好,因为:

  • 匿名方法是托管实体(使用接口实现)。它们需要适当地最终确定。
  • 动态数组本身是一种托管类型,确保匿名方法引用正确完成。
  • Delphi 2010 通用容器是使用动态数组实现的,因此它们可以胜任任务。但请确保不要一个接一个地增长数组,而是分块增长。

如果您在实现中使用其他任何东西,您需要自己负责完成引用。例子:

  • 如果您使用普通内存块,则需要一个析构函数,将每个项目故意设置为 nil(即:不是 ZeroMemory 或 FillChar),以便编译器有机会生成最终代码。
  • 记录是托管对象,它们可以保存对动态方法的引用,但它们只能保存有限数量的引用,如果您需要更多,则需要实现一种链表,然后您需要仔细管理那里的生命周期。
  • 类会遭受记录的所有缺陷,并且它们会在此之上添加自己的开销层。

【讨论】:

  • 在您的情况下,您正在实现一种基本类型(一种基本的新列表类型),我不相信可以相信泛型和编译器不会做会弄乱过程引用的事情。如果我要使用 array-of-ProcRef 以外的东西,那么我将使用 TList 并将过程引用放入记录类型中。
  • array of 适用于列表的私有实现,但我绝不希望将其用作主要数据类型。如果你不能使用TList<T>,那就创建你自己的lookalike。
猜你喜欢
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
相关资源
最近更新 更多