使用ClassHelper\record helper 给类“打补丁”

文章出處 : http://blog.sina.com.cn/s/blog_6016bdc80100dhbh.html~type=v5_one&label=rela_prevarticle?1290186141

有些时候,我们需要在现有类的基础上,给类添加一些东西
并且在类中protected区分的方法,成员是无法在单元外访问的,如果要调用它们该怎么办呢?

于是就有了以下三种方法 :

  1. 继承该类
  2. 直接覆写该类
  3. 使用Class Helper

对于第一种方法,大家都很熟悉,我就不多说了,第二种方法的实现可以参考此处(点击进入)

而第三种,就是我在本文中要说的,利用ClassHelper来实现对类的扩展,也可以称之为,给类“打补丁”

具体的操作方式如下,假设有一个很简单的类:

type
TTestClass = class
private
    FInfo: string;
protected
    procedure DoTest;
public
    function DoAdd(a,b: integer): string;
public
    property Info: string read FInfo write FInfo;
end;

我现在想给它添加一个DoMinus方法,于是就有了这个Class Helper :

type
TTestClassHelper = class helper for TTestClass
public
    function DoMinus(a,b: integer): string;
end;


可以看到,只是很简单的声明一个class helper,然后在里面添加内容。
这样做的好处是,原本的类代码不会被改动,只是扩展
在class helper内,可以访问到基类的protected, public, published区分符下的成员,属性和方法,但是不能访问private下的。

经过class helper的补丁后,我们就可以在基类的实例下调用添加的新方法了 :

var
t:TTestClass;
begin
t:=TTestClass.Create;
t.DoAdd(1,2);
t.DoMinus(2,1);
end;

这只是一个很小的例子,以前我曾经见过把class helper用得非常复杂的。它对于代码有着相当强的隐蔽性
例如:

type
TTestClass = class
protected
     FA, FB, FC: string;
public
end;

type
TTestClassHelper = class helper for TTestClass
public
    procedure Do1;
    procedure Do2;
    ......
end;

这样的代码看着真能让人头疼,按着Ctrl点类名只能看到一个空的类,没有一个方法。
实现的代码全都放在了class helper里,并且class helper也不是写在pas里,是拆分后写在inc里了

总结
class helper对于简单的对类打补丁而言,是比较有用的,毕竟写一个class helper和继承一个类差不多,而且class helper不会对基类造成影响,也不用担心一个不小心就把基类的东西override错了
但是class helper并不适合用在较大规模的类复写中,特别是用class helper来实现半开源的产品,将非常不利于代码的维护(如果是商业手段则不在此列),此时就需要较为详尽的文档来标识class helper以及其所指的类。
 
当初Delphi 2007为了兼容D2006编译的单元,才想到了用Class Helper。不过Class Helper/Record Helper只适合作为”补丁“,一般不要放到常规的设计里面。

使用了Record Helper来扩展TGuid结构,很方便。

type
   TGuidHelper = record helper for TGUID
   private
   class function GetEmpty: TGUID; static;
   public
   class function Create(const g: string): TGUID; overload; static;
   class function NewGuid: TGUID; static;
   function Equals(const guid: TGUID): Boolean;
   function ToString: string;
   class property Empty: TGUID read GetEmpty;
   end;


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、IDE 1、对IDE的高DPI支持,涵盖了最新的4k+显示器,整个字体和图标更干净、更清晰。 2、多显示器和多窗口改进:在多个窗口中同时设计和编辑同一个表单的代码 3、完全重建的欢迎页,具有原生的外观和感觉,以及适合IDE的UI,并可自定义布局和内容 4、C++代码格式化器。使用clang-format自动布局你的C++代码 5、改进了对VCL和IDE的远程桌面支持 6、FireMonkey设计时指南。通过可视化的线条和增强的边距和填充支持更快地进行原型设计 二、VCL 1、丰富的编辑组件更新删除了XP的依赖性,并为TRichEdit控件引入了新的功能。 2、VCL样式增加了设计时支持:通过在设计时立即看到你的样式表格和控件在运行时的样子,使时尚的UI原型更快。 3、增加了对TreeViews中CheckBoxes的支持,每个节点都支持3种状态(部分、变暗、排除)以帮助定制UI。 4、新的TDBLabeledEdit组件提供了TLabelEdit的数据感知版本,以加快原型设计。 5、大量的VCL改进,包括默认的表格大小和字体,例外对话框的复制按钮,备忘录和RichEdit的边距等等。 三、FMX 1、改进了对Windows和桌面的FMX高DPI支持,桌面UI明显优越 2、在WebBrowser组件中支持微软的WebView 2控件(Edge Chromium)。 3、支持最新的Android 30 API和最新的计费API,并迁移到使用AndroidX库 4、Android支持多个classes.dex文件,简化了对外部Android依赖的整合 四、Platforms 1、Delphi macOS 64位ARM编译器和工具链,包括为Intel/Arm AppStore提交构建通用二进制文件 2、Delphi语言支持二进制小数和数字分离器 3、改进了C++工具链,对C++型的RTTI进行了大修,包括在Delphi型上使用typeid。 4、为Delphi型改进了C++风格的RTTI 5、在Win32和Win64上改进了CMake的质量并大大改进了异常处理。 五、RTL 1、RTL质量重点。TZipFile、大数据结构的64位改进、蓝牙LE 2、System.DateUtils中TDateTime的记录帮助器 3、System.SysUtils中TCurrency的Record Helper使货币的工作更加简单和容易。 4、C++ RTL的改进包括在Delphi使用make_shared和make_unique,对Delphi字符串的string_view支持,以及Delphi/C++字符串的简单转换。 六、LSP 1、使用Visual Studio Code来编辑Delphi源代码,并具有完整的代码完成功能 2、LSP对Include文件的认识 3、自动重新启动LSP服务器 4、用Tab键自动完成代码 5、支持辅助工具 6、赋值数组时的数组建议 七、Data 1、新版本中的FireDAC为PostgreSQL、Oracle和Firebird数据库提供了具体的改进。 2、HTTP和REST客户端库已经扩展了超时机制,支持HTTP/2、TLS 1.3、Base64 URL编码。 3、新组件TRESTRequestDataSetAdapter简化了向服务器上传数据集的过程 4、新的低流量RAD Server Lite允许无限制地部署您的多层解决方案,以及完全可扩展的Server引擎。 5、对于DataSnap,REST URL映射逻辑现在是完全可配置的

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值