Delphi 匿名方法 - 优点和缺点。在 Delphi 中使用闭包(匿名方法)的良好实践

标签 delphi closures anonymous-methods

我的团队中有一位同事在 Delphi 开发的项目中广泛使用闭包。就我个人而言,我不喜欢这样做,因为这会让代码更难阅读,而且我相信只有在需要时才应该使用闭包。

另一方面,我读过 Can someone explain Anonymous methods to me?以及与此相关的其他链接,我考虑到也许我错了,所以我要求你给我一些例子,什么时候最好使用闭包而不是“老式”方法(不使用关闭)。

最佳答案

我认为这个问题需要非常主观的判断。我是一名老派的 Delphi 开发人员,并且倾向于同意你的观点。闭包不仅会增加某些风险(正如 David H 在评论中指出的那样),还会降低所有受过经典培训的 Delphi 开发人员的可读性。那么为什么要将它们添加到语言中呢?例如,在 Delphi XE 中,语法格式化函数和闭包不能很好地协同工作,这增加了我对闭包的不信任; Delphi 编译器中添加了多少 IDE 尚未完全升级以支持的内容?当您公开承认如果 Delphi 语言被卡住在 Delphi 7 级别并且不再改进时您会很高兴,您就知道您是一个脾气暴躁的老前辈。但 Delphi 是一种活生生的、强大的、不断发展的语法。这是一件好事。当你发现老怪人接管时,请对自己重复这句话。尝试一下。

我可以想到至少十个地方,匿名方法真正有意义,因此,你应该使用它们的原因,尽管我之前评论说我不信任它们。我只会指出我个人决定使用的两个,以及我在使用它们时给自己设置的限制:

  1. Generics.Collections 中的容器类中的排序方法接受匿名方法,以便您可以轻松提供排序逻辑,而无需编写与该方法具有相同签名的常规(非匿名)函数。排序方法期望。新的泛型语法与这种风格齐头并进,虽然它一开始对你来说看起来很陌生,但它会随着你的发展而变得越来越好用,至少比其他替代方案更方便。

    <
  2. 像Synchronize这样的TThread方法是重载的,除了支持单个TThreadMethod作为参数Thread.Synchronize(aClassMethodWithoutParameters)之外,它一直是我痛苦的根源,将参数获取到该同步方法中。现在你可以使用闭包(匿名方法),并传入参数。

我在编写匿名方法时建议的限制:

A.我个人的经验法则是每个函数只有一个闭包,只要有多个闭包,就将这段代码重构为其自己的方法。这可以防止“方法”的圈复杂度变得疯狂。

B.另外,在每个闭包内,我更喜欢只有一个方法调用及其参数,如果我最终编写了巨大的代码块,我会将它们重写为方法。闭包是为了变量捕获,而不是编写无休止扭曲的意大利面条代码的全权委托(delegate)。

样本排序:

 var     
   aContainer:TList<TPair<String, Integer>>;  
 begin   
  aContainer.Sort(    
    TMyComparer.Construct(
      function (const L, R: TPair<String, Integer>): integer
      begin
        result := SysUtils.CompareStr(L.Key,R.Key);
      end ) {Construct end}   );  {aContainer.Sort end}  
 end;

更新:一条评论指向“语言丑化”,我认为丑化指的是必须写的区别:

  x.Sort(     
    TMyComparer.Construct(
      function (const L, R: TPair<String, Integer>): integer
      begin
        result := SysUtils.CompareStr(L.Key,R.Key);
      end )   ); 

取而代之的是我刚刚在这里发明的以下假设的鸭子类型(或者我应该说推断类型)语法来进行比较:

  x.Sort( lambda( [L,R], [ SysUtils.CompareStr(L.Key,R.Key) ] ) )

其他一些语言(例如 Smalltalk 和 Python)可以更紧凑地编写 lambda,因为它们是动态类型的。例如,对 IComparer 的需求,作为传递给容器中的 Sort() 方法的类型,是由接口(interface)风格引起的复杂性的一个例子,具有泛型的强类型语言必须遵循该接口(interface)风格才能实现排序等特征,可排序性所需。我认为没有一个好的方法可以做到这一点。就我个人而言,我讨厌在函数调用括号内看到 procedure、begin 和 end 关键字,但我看不出还有什么可以合理完成的。

关于Delphi 匿名方法 - 优点和缺点。在 Delphi 中使用闭包(匿名方法)的良好实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7818759/

相关文章:

javascript - javascript中的私有(private)变量意味着

delphi - MSXML XPath 可以选择属性吗? (更新: real issue was with default no-prefix namespace )

delphi - 具有向后兼容性的数据快照维护和开发

swift - 非转义闭包的实际用途是什么?

c# - 不能从匿名方法引用非静态方法

scala - 创建未命名的隐式类或函数

c# - 如何在匿名方法中产生返回?

delphi - 使用 Delphi 进行 JNI 编程

delphi - 为什么 CharInSet 比 Case 语句更快?

javascript - 如何将三 Angular 形数组取出来以便我可以使用它