是否有一些使用of object子句声明的Delphi委托的共同祖先?

我需要为TNotifyEvent和我的自定义委托找到一个共同的祖先:

TMyEvent = procedure(Sender: TObject; msg: stringh); of object;


为触发这些事件提供一种通用方法。

我应该使用指针吗?还是TObject?

最佳答案

您需要认真研究method pointers的实现细节。这些被存储为所谓的双指针值。一个用于方法调用主题的指针(实例),一个用于方法本身的指针(代码)。

您可以使用TMethod单元中的System类型来表示方法指针。它的声明看起来像这样(为简单起见删除了比较运算符):

type
  TMethod = record
    Code, Data: Pointer;
  end;


您需要使用类型转换在以下类型之间进行分配:

uses
  System.Classes;

var
  Event: TNotifyEvent;
  Method: TMethod;

begin
  Method := TMethod(Event);
  TMethod(Event) := Method;
end.


显然,这都不是类型安全的,因此您需要确保正确性。编译器无法帮助您。没有什么方法像检查类型转换运算符as可以与方法指针一起使用。也就是说,由您决定,当您从TMethod强制转换为特定的方法指针类型时,必须确保TMethod实例确实是您要强制转换为方法指针类型的实例。认为整个过程类似于从类型化的指针转换为非类型化的指针,然后再次返回。

现在,如果要将任意方法指针存储到TMethod实例中,那很好。但是,当您随后需要触发这些方法时会发生什么。您需要知道每种TMethod实例背后实际上是哪种类型的方法指针。这样您就知道如何强制转换,需要什么参数以及如何调用它。这将意味着您必须与原始方法本身一起存储有关方法的真实类型的额外信息。

因此,我认为我也许已经回答了您提出的问题,但是我不确定这对您是否有用。要了解这一点,我认为我们真的需要更多地了解您想要达到的目标以及何时拥有什么信息。

例如,如果您在需要存储该方法时知道要传递给该方法的参数,则可以使用变量捕获并将其包装在匿名方法中。这样可以使您保持类型安全,并避免我在上面演示的任何相当可疑的强制转换。也许您需要partial application,作为使非均质方法指针具有相同接口的一种方法。在这种情况下,匿名方法同样可以提供帮助。

09-03 19:44