zoukankan      html  css  js  c++  java
  • 关于 class helper for ... 语法

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

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

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

    例一:

    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 及其所有子孙类就都拥有了这个方法.

    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.
    

     菜根大神的方法

    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;
    

      

  • 相关阅读:
    MYSQL长连接的一个小问题
    wpf关于PasswordBox的绑定Password的问题(MVVM框架)
    关于C# DataGridView 全选与取消的小问题
    谈谈在京东手机APP的产品推荐
    赵海平给中国开发者的建议
    python_闭包_匿名函数
    mysql远程连接10038错误
    计算机系统 -- 计算机
    Java——类和对象
    ORACLE数据库定时任务—DBMS_JOB
  • 原文地址:https://www.cnblogs.com/sttchengfei/p/10471864.html
Copyright © 2011-2022 走看看