关于 class helper for ... 语法

转载于万一的博客https://www.cnblogs.com/del/archive/2009/10/13/1582789.html

 

class helper 可能是从 Delphi 2007 增加的新语法, 因为感觉不太实用, 直到今天才测试了一下.
试过之后才知道: 挺有意思的! 基本功能就是修改已存在的类.

1
2
3
4
5
6
Txxx = class helper for T... {T... 表示已存在的类}
  {可以替换已存在的方法}
  {也可以有新的方法、成员}
end;
 
//这之后再使用 T... 类及其子孙类时, 都会优先使用 Txxx 的修改

例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
 
  TMyClass = class
    function func1: string;
    function func2: string;
  end;
 
  TMyClassHelper = class helper for TMyClass
    function func1: string; {将把 TMyClass 的同名方法替换掉}
    function func3: string; {将为 TMyClass 及其子类增加这个方法}
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
{ TMyClass }
 
function TMyClass.func1: string;
begin
  Result := 'TMyClass.func1';
end;
 
function TMyClass.func2: string;
begin
  Result := 'TMyClass.func2';
end;
 
{ TMyClassHelper }
 
function TMyClassHelper.func1: string;
begin
  Result := 'TMyClassHelper.func1';
end;
 
function TMyClassHelper.func3: string;
begin
  Result := 'TMyClassHelper.func3';
end;
 
//测试
procedure TForm1.Button1Click(Sender: TObject);
var
  obj: TMyClass;
begin
  obj := TMyClass.Create;
 
  ShowMessage(obj.func1); {TMyClassHelper.func1}
  ShowMessage(obj.func2); {TMyClass.func2}
  ShowMessage(obj.func3); {TMyClassHelper.func3}
 
  obj.Free;
end;
 
end.

例二: 本例为 TControl 类增加了一个方法, 之后 TControl 及其所有子孙类就都拥有了这个方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
 
  TMyClassHelper = class helper for TControl
    procedure MyMsg;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
{ TMyClassHelper }
 
procedure TMyClassHelper.MyMsg;
begin
  ShowMessageFmt('%s 的类名是 %s', [Name,ClassName]);
end;
 
//测试: 这里测试了当前窗体和当前按钮, 它们都是从 TControl 继承来的
procedure TForm1.Button1Click(Sender: TObject);
begin
  Self.MyMsg;            {Form1 的类名是 TForm1}
  TButton(Sender).MyMsg; {Button1 的类名是 TButton1}
end;
 
end.

 菜根大神的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
type
  TMyObject = class
  private
    FX : Integer;
  public
    property X: Integer read FX write FX;
  end;
 
type
  TMyObjectHelper = class helper for TMyObject
  type
    PMyObjHelperData = ^TMyObjHelperData;
    TMyObjHelperData = record
    public
      FY: Integer;
    end;
  private
    class constructor Create;
  public
    function GetData: PMyObjHelperData;
    function GetXYValue : Integer;
    procedure SetY(Y: Integer);
  end;
 
class constructor TMyObjectHelper.Create;
var
  P: Pointer;
  ASize: Integer;
  T: NativeUInt;
begin
  P := PByte(TMyObject) + vmtInstanceSize;
  ReadProcessMemory(GetCurrentProcess, P, @ASize, SizeOf(ASize), T);
  Inc(ASize, SizeOf(TMyObjHelperData));
  WriteProcessMemory(GetCurrentProcess, P, @ASize, SizeOf(ASize), T);
end;
 
function TMyObjectHelper.GetData: PMyObjHelperData;
begin
  Result :=
    Pointer(PByte(Self) + InstanceSize - hfFieldSize + hfMonitorOffset - SizeOf(TMyObjHelperData));
end;
 
function TMyObjectHelper.GetXYValue : Integer;
var
  AData: PMyObjHelperData;
begin
  AData := GetData;
  Result:= FX + AData.FY;
end;
 
procedure TMyObjectHelper.SetY(Y: Integer);
var
  AData: PMyObjHelperData;
begin
  AData := GetData;
  AData.FY := Y;
end;
 
procedure TForm1.Button5Click(Sender: TObject);
var
  AObj: TMyObject;
begin
  AObj := TMyObject.Create;
  AObj.X := 200;
  AObj.SetY(100);
  ShowMessage(AObj.GetXYValue.ToString);
  AObj.Free;
end;

  

posted @   _成飞  阅读(353)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示