delphi – 如何检查两个方法引用是否引用相同的方法?
发布时间:2020-12-15 10:15:16 所属栏目:大数据 来源:网络整理
导读:我正在尝试列出处理程序是方法引用的事件处理程序。 要删除特定的处理程序,我需要在列表中找到它。 但是如何比较两个方法引用的代码地址? type TEventHandler = reference to procedure;procedure TestProc;beginend;procedure TForm26.FormCreate(Sender:
我正在尝试列出处理程序是方法引用的事件处理程序。
要删除特定的处理程序,我需要在列表中找到它。 但是如何比较两个方法引用的代码地址? type TEventHandler = reference to procedure; procedure TestProc; begin end; procedure TForm26.FormCreate(Sender: TObject); var Handlers: TList<TEventHandler>; begin Handlers := TList<TEventHandler>.create; try Handlers.Add(TestProc); Handlers.Remove(TestProc); { doesn't work } Assert(Handlers.Count=0); { fails } Assert(Handlers.IndexOf(TestProc)>=0); { fails } finally FreeAndNil(Handlers); end; end; TList的默认比较器不正确比较方法参考。 解决方法
这不像看起来那么容易。
要了解为什么会发生这种情况,您需要了解编译器如何执行方法引用的分配。 您编写的代码基本上由编译器翻译成: Handlers.Add(procedure begin TestProc; end); Handlers.Remove(procedure begin TestProc; end); 现在我们必须知道,如果您在同一个例程中有多个匿名方法,那么即使他们的代码是相同的,它们实际上也是不同的匿名方法。 (见How are anonymous methods implemented under the hood?) 这意味着传递给“添加和删除”的值即使其身体中的代码是相同的,即使是黑客也需要二进制代码分析来确定正文中的代码是否相同。 如果你改变代码如下,它将工作,因为你只有一个匿名方法 – 为这个剪辑它的工作,但通常你不会添加和删除在完全相同的例程: var Handlers: TList<TEventHandler>; Handler: TEventHandler; begin Handlers := TList<TEventHandler>.create; try Handler := TestProc; Handlers.Add(Handler); Handlers.Remove(Handler); Assert(Handlers.Count=0); finally FreeAndNil(Handlers); end; end; 如果您想要添加和删除事件处理程序的列表,我的个人建议是避免匿名方法类型并使用过程或方法: type TEventHandlerA = procedure; TEventHandlerB = procedure of object; 最好的决定取决于你,因为你的代码更好。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |